diff --git a/.dockerignore b/.dockerignore index bc81c05a6..10c77be03 100644 --- a/.dockerignore +++ b/.dockerignore @@ -17,6 +17,7 @@ CMakeLists.txt.user* *.tmp *.old *.srctrl* +*.log /*.vt? /*.root diff --git a/.gitignore b/.gitignore index 747eded20..53e862155 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,6 @@ cmake_install.cmake /*.sh /*.gpl /**/*.egg-info +/*.log + +!/setup.sh \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index a2262b68a..480d27ae5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,15 +8,15 @@ When bumping a module version, also provide a date to indicate the last update. ## Current version -The current Kassiopeia version is v3.7 released on May 1, 2020. -The latest update v3.7.7 was released on January 13, 2021. +The current Kassiopeia version is v3.8 released on Aug 27, 2021. + Module versions: -* **Kassiopeia** 3.7.5 (Jan 13, 2021) -* **KEMField** 3.7.5 (Jan 13, 2021) -* **KGeoBag** 3.7.5 (Jan 13, 2021) -* **Kommon** 1.4.1 (Jan 13, 2021) -* **UnitTest** 0.2.5 (Nov 30, 2020) +* **Kassiopeia** 3.8.0 (Aug 27, 2021) +* **KEMField** 3.8.0 (Aug 27, 2021) +* **KGeoBag** 3.8.0 (Aug 27, 2021) +* **Kommon** 1.5.0 (Aug 27, 2021) +* **UnitTest** 0.2.5 (Jun 2, 2021) +## Changes in v3.8.0 + +Kassiopeia v3.8.0 was released on August 27, 2021. +[Details](https://github.com/KATRIN-Experiment/Kassiopeia/releases/tag/v3.8.0) + +[*View Changelog*](Changelog/changes-from-v3.7.7-to-v3.8.0.md) + ## Changes in v3.7.7 Kassiopeia v3.7.7 was released on January 13, 2021. diff --git a/CMakeLists.txt b/CMakeLists.txt index fae10daeb..01a486f27 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,24 +1,21 @@ -set( CMAKE_MINIMUM_VERSION "3.13.0" ) +set( CMAKE_MINIMUM_VERSION "3.14.0" ) cmake_minimum_required( VERSION ${CMAKE_MINIMUM_VERSION} ) # project version set(KASPER_VERSION_MAJOR 3) -set(KASPER_VERSION_MINOR 7) -set(KASPER_VERSION_PATCH 7) +set(KASPER_VERSION_MINOR 8) +set(KASPER_VERSION_PATCH 0) set(KASPER_VERSION "${KASPER_VERSION_MAJOR}.${KASPER_VERSION_MINOR}.${KASPER_VERSION_PATCH}") -#project( Kasper VERSION ${KASPER_VERSION} ) -project( Kasper ) - -# Silently try to find major dependencies. This list is not be complete! -# (Somehow, CMake behaves better if this is done in the root scope before adding modules...) -#find_package(Boost COMPONENTS QUIET) -#find_package(HDF5 COMPONENTS CXX QUIET) -#find_package(ROOT QUIET) -find_package(MPI QUIET) -find_package(VTK QUIET) +#project( Kasper ) +project( Kasper VERSION ${KASPER_VERSION} + DESCRIPTION "The KATRIN Analysis and Simulations Package" + LANGUAGES CXX ) set( BUILD_SHARED_LIBS ON ) +set( Boost_USE_STATIC_LIBS OFF ) +set( Boost_USE_MULTITHREADED ON ) +set( Boost_USE_STATIC_RUNTIME OFF ) set( CMAKE_CXX_STANDARD 14 CACHE STRING "The C++ standard whose features are requested to build this target" ) set( CMAKE_CXX_STANDARD_REQUIRED ON ) @@ -28,18 +25,18 @@ set( CMAKE_EXPORT_COMPILE_COMMANDS ON ) # Additional compiler version checks, see https://en.cppreference.com/w/cpp/compiler_support if( CMAKE_SYSTEM_NAME STREQUAL "Linux" ) if( CMAKE_CXX_COMPILER_ID STREQUAL "GNU" ) - if( CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0" ) - message(WARNING "Your compiler is unsupported! You need at least GCC 5.0 to build Kasper.") + if( CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.1" ) + message(FATAL_ERROR "Your compiler is unsupported! You need at least GCC 6.1 to build Kasper.") endif() elseif( CMAKE_CXX_COMPILER_ID STREQUAL "Clang" ) if( CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.4" ) - message(WARNING "Your compiler is unsupported! You need at least Clang 3.4 to build Kasper.") + message(FATAL_ERROR "Your compiler is unsupported! You need at least Clang 3.4 to build Kasper.") endif() endif() elseif( CMAKE_SYSTEM_NAME STREQUAL "Darwin" ) if( CMAKE_CXX_COMPILER_ID STREQUAL "Clang" ) if( CMAKE_CXX_COMPILER_VERSION VERSION_LESS "10.0" ) - message(WARNING "Your compiler is unsupported! You need at least Clang 10.0 to build Kasper.") + message(FATAL_ERROR "Your compiler is unsupported! You need at least Clang 10.0 to build Kasper.") endif() endif() else() @@ -63,17 +60,12 @@ set( CMAKE_BUILD_WITH_INSTALL_RPATH FALSE ) # which point to directories outside the build tree to the install RPATH set( CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE ) if( APPLE ) - set(CMAKE_INSTALL_RPATH "@executable_path/../${CMAKE_INSTALL_LIBDIR};@loader_path") + #set( CMAKE_INSTALL_RPATH "@executable_path/../${CMAKE_INSTALL_LIBDIR};@loader_path" ) + set( CMAKE_MACOSX_RPATH TRUE ) elseif( UNIX ) - set(CMAKE_INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}") + set( CMAKE_INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}" ) endif( APPLE ) -# the RPATH to be used when installing, but only if it's not a system directory -#LIST( FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${LIB_INSTALL_DIR}" isSystemDir ) -#IF( "${isSystemDir}" STREQUAL "-1" ) -# set( CMAKE_INSTALL_RPATH "${LIB_INSTALL_DIR}" ) -#ENDIF() - # Flags for all modules, every module should have a flag. @@ -102,39 +94,34 @@ endif() # We like the compiler to be more pedantic than usual :-P add_compile_options( -Wall -Wextra -Werror ) +# Only link in libraries that we actually need (but not for executables since it makes things slow) +set(_target_type "$") +add_link_options( $,LINKER:--as-needed,LINKER:--no-as-needed> ) + # Enable some advanced options depending on build type if (CMAKE_BUILD_TYPE MATCHES Rel) option( COMPILER_TUNE_OPTIONS "Enable additional tuning options [compiles for local CPU, use with care!]" OFF ) + mark_as_advanced(COMPILER_TUNE_OPTIONS) if( COMPILER_TUNE_OPTIONS ) # These are advanced options for GCC which might improve performance ... or break everything - use with care! add_compile_options( -march=native -mfpmath=sse -funroll-loops ) endif( COMPILER_TUNE_OPTIONS ) endif() -if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR CMAKE_COMPILER_IS_GNUCXX ) - if( NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "7.0" ) - # Use -faligned-new flag to trick gcc into using aligned allocators CL types. - # This is only used by KEMField, but required here because of include files. - add_compile_options($<$:-faligned-new>) - endif() - - # Enable some advanced options - option( GCC_FORCE_LINKING "Fix linker errors with some GCC versions by adding the --no-as-needed flag" ON ) - if( GCC_FORCE_LINKING ) - add_link_options( -Wl,--no-as-needed ) - endif( GCC_FORCE_LINKING ) - +if( CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_COMPILER_IS_GNUCXX ) option( GCC_REDUCE_MEMORY "Significantly reduce GCC memory usage by setting ftrack-macro-expansion=1 (default: 2)" ON ) + mark_as_advanced(GCC_REDUCE_MEMORY) if( GCC_REDUCE_MEMORY ) add_compile_options( -ftrack-macro-expansion=1 ) endif( GCC_REDUCE_MEMORY ) option( GCC_ENABLE_PIPES "Use pipes to speed up compiling with GCC by adding the -pipe flag" ON ) + mark_as_advanced(GCC_ENABLE_PIPES) if( GCC_ENABLE_PIPES ) add_compile_options( -pipe ) endif( GCC_ENABLE_PIPES ) -else( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) +else( CMAKE_CXX_COMPILER_ID STREQUAL "Clang" ) # Suppress warnings about unknown warning options. See https://bugs.llvm.org/show_bug.cgi?id=24979 add_compile_options( -Wno-unknown-warning-option ) @@ -142,6 +129,7 @@ endif() # Enable some advanced options (compiler-independent) option( ENABLE_PROFILING "Enable profiling (gperftools-based, adds '-lprofile' flag to linker calls)" OFF ) +mark_as_advanced(ENABLE_PROFILING) if( ENABLE_PROFILING ) find_library( PROFILER_LIBRARY profiler ) if ( PROFILER_LIBRARY ) @@ -149,17 +137,29 @@ if( ENABLE_PROFILING ) endif( PROFILER_LIBRARY ) endif( ENABLE_PROFILING ) +# Check for memory errors using clang's AddressSanitizer. See https://github.com/google/sanitizers/wiki/AddressSanitizer +option( ENABLE_SANITIZE_ADDRESSES "Enable memory error detection (asan-based, adds '-fsanitize=address' flag)" OFF ) +mark_as_advanced(ENABLE_SANITIZE_ADDRESSES) +if( ENABLE_SANITIZE_ADDRESSES ) + add_compile_options( -O1 -g -fno-omit-frame-pointer -fsanitize=address -fno-optimize-sibling-calls ) + add_link_options( -g -fno-omit-frame-pointer -fsanitize=address ) + if( CMAKE_CXX_COMPILER_ID STREQUAL "Clang" ) + # See https://github.com/google/sanitizers/issues/1017 + add_compile_options( -mllvm -asan-use-private-alias=1 ) + endif() +endif( ENABLE_SANITIZE_ADDRESSES ) + # Force coloured compiler output (useful for Ninja builds) -if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) +if( CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" ) option( FORCE_COLOURED_OUTPUT "Always produce ANSI-colored output (GNU/Clang only)." OFF ) - if( NOT DEFINED FORCE_COLOURED_OUTPUT AND "${CMAKE_GENERATOR}" MATCHES "Ninja" ) + if( NOT DEFINED FORCE_COLOURED_OUTPUT AND CMAKE_GENERATOR MATCHES "Ninja" ) message(STATUS "Building with Ninja - enabling coloured compiler output.") set( FORCE_COLOURED_OUTPUT ON CACHE BOOL "" FORCE ) endif() if( FORCE_COLOURED_OUTPUT ) - if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" ) + if( CMAKE_CXX_COMPILER_ID STREQUAL "GNU" ) add_compile_options( -fdiagnostics-color=always ) - elseif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) + elseif( CMAKE_CXX_COMPILER_ID STREQUAL "Clang" ) add_compile_options( -fcolor-diagnostics ) endif() endif( FORCE_COLOURED_OUTPUT ) @@ -169,19 +169,48 @@ mark_as_advanced( CLEAR CMAKE_VERBOSE_MAKEFILE ) # Global dependency options -option( KASPER_USE_BOOST "Build Boost dependent modules" ON ) -option( KASPER_USE_ROOT "Build ROOT dependent modules" ON ) -option( KASPER_USE_GSL "Build GSL dependent modules" OFF ) -option( KASPER_USE_VTK "Build VTK dependent modules" OFF ) +#find_package(Boost QUIET) +#option( KASPER_USE_BOOST "Build Boost dependent modules" ${Boost_FOUND} ) +set(KASPER_USE_BOOST ON) -# Advanced options mainly for testing -option( KASPER_EXPERIMENTAL "Enable some experimental features" OFF ) -if( KASPER_EXPERIMENTAL ) - option( KASPER_USE_TBB "Build TBB dependent modules" OFF ) - if( KASPER_USE_TBB ) - message( "WARNING: Enabling TBB can produce inconsistent or wrong results in KaFit. It is strongly recommended to leave this option disabled until further investigation." ) - endif() -endif( KASPER_EXPERIMENTAL ) +find_package(ROOT QUIET) +if(ROOT_FOUND AND NOT DEFINED KASPER_USE_ROOT) + message("ROOT was found and enabled automatically. Set KASPER_USE_ROOT=OFF to change this.") +endif() +option( KASPER_USE_ROOT "Build ROOT dependent modules" ${ROOT_FOUND} ) + +find_package(GSL QUIET) +if(GSL_FOUND AND NOT DEFINED KASPER_USE_GSL) + message("GSL was found and enabled automatically. Set KASPER_USE_GSL=OFF to change this.") +endif() +option( KASPER_USE_GSL "Build GSL dependent modules" ${GSL_FOUND} ) + +find_package(VTK QUIET) +if(VTK_FOUND AND NOT DEFINED KASPER_USE_VTK) + message("VTK was found and enabled automatically. Set KASPER_USE_VTK=OFF to change this.") +endif() +option( KASPER_USE_VTK "Build VTK dependent modules" ${VTK_FOUND} ) + +option( KASPER_USE_XGBOOST"Build XGBOOST dependent modules" OFF ) + +# Make sure that version requirements are fulfilled +if( KASPER_USE_BOOST ) + set(BOOST_MINIMUM_VERSION "1.65") + find_package(Boost ${BOOST_MINIMUM_VERSION} REQUIRED) +endif( KASPER_USE_BOOST ) + +if( KASPER_USE_ROOT ) + set(ROOT_MINIMUM_VERSION "6.16") + find_package(ROOT ${ROOT_MINIMUM_VERSION} CONFIG REQUIRED) +endif( KASPER_USE_ROOT ) + +if( KASPER_USE_GSL ) + find_package( GSL REQUIRED ) +endif( KASPER_USE_GSL ) + +if( KASPER_USE_VTK ) + find_package(VTK REQUIRED) +endif( KASPER_USE_VTK ) # Make sure all dependencies are being built # Every module must be listed before its dependencies and activate ONLY its @@ -210,7 +239,6 @@ if( BUILD_KGEOBAG ) message("KGeoBag requires GSL to be enabled in Kasper (activated automatically)" ) endif() set( KASPER_USE_GSL ON CACHE BOOL "(Required)" FORCE ) - set( KASPER_USE_BOOST ON CACHE BOOL "(Required)" FORCE ) endif( BUILD_KGEOBAG ) # Build modules @@ -221,14 +249,17 @@ if( BUILD_KOMMON ) endif() if( BUILD_KGEOBAG ) + # needs Kommon add_subdirectory( KGeoBag ) endif() if( BUILD_KEMFIELD ) + # needs Kommon, KGeoBag add_subdirectory( KEMField ) endif() if( BUILD_KASSIOPEIA ) + # needs Kommon, KGeoBag, KEMField add_subdirectory( Kassiopeia ) endif() @@ -271,8 +302,6 @@ message("\n Build was configured. Run `${CMAKE_MAKE_PROGRAM_NAME}` to start th # Install common project files -install( EXPORT KasperTargets DESTINATION ${CMAKE_INSTALL_DIR}/${PROJECT_NAME} ) - configure_file( KasperVersion.h.in ${CMAKE_CURRENT_BINARY_DIR}/KasperVersion.h @ONLY ) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/KasperVersion.h DESTINATION ${INCLUDE_INSTALL_DIR} ) diff --git a/Changelog/changes-from-v3.7.7-to-v3.8.0.md b/Changelog/changes-from-v3.7.7-to-v3.8.0.md new file mode 100644 index 000000000..8b97b05ac --- /dev/null +++ b/Changelog/changes-from-v3.7.7-to-v3.8.0.md @@ -0,0 +1,56 @@ +# Kasper Changelog + +## Changes from v3.7.7 (2021-01-13) to HEAD (2021-08-27) +### Changelog +### Docker +### Documentation +- **2021-06-02:** Update from Kasper develop (9d210e7f3c) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//5c8addc5424700580ffc112ea0433d9eb44110ad) +### Examples +- **2021-06-02:** Update from Kasper develop (37c373cbfa) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//68f74d12b8117ef4994519a5264170f8ae1d1712) +### KEMField +- **2021-08-27:** Bump version numbers [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//b33374996cdcb7a50731e4e685563673d3022000) +- **2021-08-11:** Update from Kasper develop (3fb2d8a6) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//b27ad716848bd0b7d31812fe6e7cf687b7dc06be) +- **2021-06-02:** Update from Kasper develop (9d210e7f3c) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//5c8addc5424700580ffc112ea0433d9eb44110ad) +- **2021-06-02:** Update from Kasper develop (37c373cbfa) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//68f74d12b8117ef4994519a5264170f8ae1d1712) +- **2021-06-02:** Update from Kasper develop (20f6089daa) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//48171a38468262a0a67d12d8b90002d0375df548) +- **2021-04-13:** KEMField: some additional checks for magnetic field map [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//f7cf19e05e7a492d8aadd5ebc8b3eeab544be579) +- **2021-04-13:** Feature: numeric gradient determination on magnetic fieldmaps with only field values (#48) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//bce36dcf35bffebe83ecf3f592bbfba68d21b6ce) +- **2021-02-23:** KEMField: fix magnetic field build issue [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//1c1aaf41201ae8460d9443050fa79a3d655e32f2) +- **2021-02-22:** Feature: fieldmap superposition with position check and requirement options (#46) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//e76bca4daf47f47a094d4c7957506ef4253369d5) +- **2021-02-22:** Bugfix: new save_magfield3 should respect directory in same element (#44) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//9d47c8a98de44d353f45e19bc5577e5f04b20fb0) +### KGeoBag +- **2021-08-27:** Bump version numbers [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//b33374996cdcb7a50731e4e685563673d3022000) +- **2021-08-26:** Update from Kasper develop (25cb1351) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//2388023a073f6e734cbb65e544aab70bace82313) +- **2021-08-11:** Update from Kasper develop (3fb2d8a6) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//b27ad716848bd0b7d31812fe6e7cf687b7dc06be) +- **2021-06-02:** Update from Kasper develop (9d210e7f3c) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//5c8addc5424700580ffc112ea0433d9eb44110ad) +- **2021-06-02:** Update from Kasper develop (37c373cbfa) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//68f74d12b8117ef4994519a5264170f8ae1d1712) +- **2021-06-02:** Update from Kasper develop (20f6089daa) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//48171a38468262a0a67d12d8b90002d0375df548) +### Kassiopeia +- **2021-08-27:** Bump version numbers [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//b33374996cdcb7a50731e4e685563673d3022000) +- **2021-08-26:** Update from Kasper develop (25cb1351) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//2388023a073f6e734cbb65e544aab70bace82313) +- **2021-08-11:** Update from Kasper develop (3fb2d8a6) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//b27ad716848bd0b7d31812fe6e7cf687b7dc06be) +- **2021-06-09:** Update from Kasper develop (fce0771c) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//54496575e921f61e045f948653557d06ffd1eda1) +- **2021-06-02:** Update from Kasper develop (9d210e7f3c) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//5c8addc5424700580ffc112ea0433d9eb44110ad) +- **2021-06-02:** Update from Kasper develop (37c373cbfa) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//68f74d12b8117ef4994519a5264170f8ae1d1712) +- **2021-06-02:** Update from Kasper develop (20f6089daa) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//48171a38468262a0a67d12d8b90002d0375df548) +- **2021-04-16:** Kassiopeia: `KassiopeiaReader` example for updated user guide [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//f012ccb861e7066cbb74091fe65234fc9275c722) +- **2021-04-14:** Kassiopeia: update `KassiopeiaReader` and provide example [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//449debc6b0899ee9ce880d39cc2028db5753768c) +- **2021-04-13:** KEMField: some additional checks for magnetic field map [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//f7cf19e05e7a492d8aadd5ebc8b3eeab544be579) +- **2021-02-21:** root_magfield_painter: avoid division by zero when |B| = 0 [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//7217df5e35c3851dc151a70db4390f3a70f48f4e) +- **2021-02-20:** Gradient plotting requires dividing by |B|, not multiplying [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//44f65785da8adc5ae8a8df47a09a8a84f1f0071a) +- **2021-01-23:** ROOT track painter implementation on plane defined by point and normal [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//9e63d3eebf5b3e4e7eda51dd622249d47d88038b) +- **2021-01-23:** Provide plane_normal, plane_point, swap_axis, epsilon from root_geometry_painter in root_track_painter [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//efce92bdbffaed238092c3328a7da1e164feaf55) +### Kommon +- **2021-08-27:** Bump version numbers [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//b33374996cdcb7a50731e4e685563673d3022000) +- **2021-08-26:** Update from Kasper develop (25cb1351) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//2388023a073f6e734cbb65e544aab70bace82313) +- **2021-08-11:** Update from Kasper develop (3fb2d8a6) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//b27ad716848bd0b7d31812fe6e7cf687b7dc06be) +- **2021-06-10:** Update from Kasper develop (1f46fd39) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//5eb2a68b5d7f3ff1e0cc1970e72b5ed8b560a5e3) +- **2021-06-09:** Update from Kasper develop (fce0771c) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//54496575e921f61e045f948653557d06ffd1eda1) +- **2021-06-02:** Update from Kasper develop (9d210e7f3c) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//5c8addc5424700580ffc112ea0433d9eb44110ad) +- **2021-06-02:** Update from Kasper develop (37c373cbfa) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//68f74d12b8117ef4994519a5264170f8ae1d1712) +- **2021-06-02:** Update from Kasper develop (20f6089daa) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//48171a38468262a0a67d12d8b90002d0375df548) +### Scripts +- **2021-08-11:** Update from Kasper develop (3fb2d8a6) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//b27ad716848bd0b7d31812fe6e7cf687b7dc06be) +- **2021-06-02:** Update dependency graphs and requirements [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//d29c228f2222691ae0c15343d989581813a5af8f) +### UnitTest +- **2021-06-02:** Update from Kasper develop (9d210e7f3c) [*(view commit)*](https://github.com/KATRIN-Experiment/Kassiopeia/commit//5c8addc5424700580ffc112ea0433d9eb44110ad) diff --git a/Dockerfile b/Dockerfile index 74474b2b3..e9913eda0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,32 +1,32 @@ +# --- runtime-base --- FROM fedora:31 as runtime-base LABEL description="Runtime base container" -LABEL maintainer=wdconinc@gmail.com +LABEL maintainer="jan.behrens@kit.edu" COPY Docker/packages.runtime packages RUN dnf update -y \ && dnf install -y $(cat packages) \ && rm /packages - +# --- build-base --- FROM runtime-base as build-base LABEL description="Build base container" -LABEL maintainer=wdconinc@gmail.com COPY Docker/packages.build packages RUN dnf update -y \ && dnf install -y $(cat packages) \ && rm /packages - +# --- build --- FROM build-base as build LABEL description="Build container" -LABEL maintainer=wdconinc@gmail.com -COPY . . -RUN mkdir -p build && \ +COPY . /usr/src/kasper +RUN cd /usr/src/kasper && \ + mkdir -p build && \ pushd build && \ cmake -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr/local \ @@ -40,11 +40,10 @@ RUN mkdir -p build && \ make install && \ popd - +# --- runtime --- FROM runtime-base as runtime LABEL description="Run container" -LABEL maintainer=wdconinc@gmail.com COPY --from=build /usr/local /usr/local RUN echo "/usr/local/lib64" > /etc/ld.so.conf.d/local-x86_64.conf \ diff --git a/Documentation/CMakeLists.txt b/Documentation/CMakeLists.txt index 96b951b99..2fffb19e2 100644 --- a/Documentation/CMakeLists.txt +++ b/Documentation/CMakeLists.txt @@ -1,6 +1,6 @@ if(BUILD_DOC) - add_subdirectory(DeveloperGuide) - add_subdirectory(ComponentDocumentation) + add_subdirectory(DeveloperGuide) + add_subdirectory(ComponentDocumentation) endif(BUILD_DOC) # Doxygen looks into all activated module dirs @@ -8,7 +8,7 @@ get_property(MODULE_DIRS GLOBAL PROPERTY MODULE_DIRS) list(JOIN MODULE_DIRS " \\\n " KASPER_SOURCE_DIRS) if( VTK_MAJOR_VERSION GREATER 5 ) - set( KASPER_PREDEFS VTK6 ) + set( KASPER_PREDEFS VTK6 ) endif() kasper_add_doc_reference(kasper.doxygen) diff --git a/Examples/CMakeLists.txt b/Examples/CMakeLists.txt index 9adad37b0..3bbcb72fd 100644 --- a/Examples/CMakeLists.txt +++ b/Examples/CMakeLists.txt @@ -6,16 +6,14 @@ project(Kassiopeia-Examples) message("CMake prefix path: ${CMAKE_PREFIX_PATH}") find_package(Boost REQUIRED COMPONENTS filesystem) -find_package(VTK) -if(VTK_FOUND) - include(${VTK_USE_FILE}) -endif(VTK_FOUND) +find_package(VTK CONFIG REQUIRED) # Don't forget to set CMAKE_PREFIX_PATH to your Kasper installation folder # before executing cmake. That way, CMake will be able to find the KaLi installation. -find_package(Kassiopeia REQUIRED) -find_package(KEMField REQUIRED) +find_package(Kommon REQUIRED) find_package(KGeoBag REQUIRED) +find_package(KEMField REQUIRED) +find_package(Kassiopeia REQUIRED) # Set the default install prefix (you don't need to remember this) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) @@ -27,13 +25,6 @@ set( CMAKE_CXX_STANDARD 14 ) set( CMAKE_CXX_STANDARD_REQUIRED ON ) set( CMAKE_CXX_EXTENSIONS OFF ) -# Define your include directories -include_directories ( - ${Kassiopeia_INCLUDE_DIRS} - ${KEMField_INCLUDE_DIRS} - ${KGeoBag_INCLUDE_DIRS} -) - SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) #---------------------------------------- @@ -52,7 +43,7 @@ set( EXECUTABLES foreach(EXECUTABLE ${EXECUTABLES}) add_executable(${EXECUTABLE} ${EXECUTABLE}.cxx) - target_link_libraries (${EXECUTABLE} ${Kassiopeia_LIBRARIES}) + target_link_libraries (${EXECUTABLE} Kassiopeia::KassiopeiaBindings) endforeach() # Define a cmake install target diff --git a/KEMField/CMakeLists.txt b/KEMField/CMakeLists.txt index 81e08f460..6c25e2824 100644 --- a/KEMField/CMakeLists.txt +++ b/KEMField/CMakeLists.txt @@ -6,8 +6,8 @@ endif() # KEMField version set(MODULE_VERSION_MAJOR 3) -set(MODULE_VERSION_MINOR 7) -set(MODULE_VERSION_PATCH 7) +set(MODULE_VERSION_MINOR 8) +set(MODULE_VERSION_PATCH 0) set(MODULE_VERSION "${MODULE_VERSION_MAJOR}.${MODULE_VERSION_MINOR}.${MODULE_VERSION_PATCH}") project( KEMField ) @@ -16,40 +16,44 @@ include( KasperDefaults ) # module options -#option (${PROJECT_NAME}_USE_VTK "Enables the use of VTK for visualization" OFF) -set (${PROJECT_NAME}_USE_VTK ${KASPER_USE_VTK}) -if (${PROJECT_NAME}_USE_VTK) - kasper_find_vtk() -endif() +#option (KEMField_SILENT "Disable all messaging" OFF) + +#cmake_dependent_option (KEMField_USE_KMESSAGE "Use KMessage" ON "NOT KEMField_SILENT" OFF) +set (KEMField_USE_KMESSAGE ON) + +option (KEMField_USE_MPI "Use MPI to accelerate calculations using multiple processors" OFF) +if (KEMField_USE_MPI) + find_package(MPI REQUIRED) +endif (KEMField_USE_MPI) -#option (${PROJECT_NAME}_USE_ROOT "Link against ROOT" OFF) -set (${PROJECT_NAME}_USE_ROOT ${KASPER_USE_ROOT}) -if (${PROJECT_NAME}_USE_ROOT) - find_package(ROOT REQUIRED) +#option (KEMField_USE_VTK "Enables the use of VTK for visualization" OFF) +set (KEMField_USE_VTK ${KASPER_USE_VTK}) +if (KEMField_USE_VTK) + find_package(VTK CONFIG REQUIRED) endif() +#option (KEMField_USE_ROOT "Link against ROOT" OFF) +set (KEMField_USE_ROOT ${KASPER_USE_ROOT}) +if (KEMField_USE_ROOT) + find_package(ROOT REQUIRED) +endif (KEMField_USE_ROOT) + #option (KEMField_USE_GSL "Use GSL" OFF) -set (${PROJECT_NAME}_USE_GSL ${KASPER_USE_GSL}) -if (${PROJECT_NAME}_USE_GSL) - find_package(GSL REQUIRED) -endif () +set (KEMField_USE_GSL ${KASPER_USE_GSL}) +if (KEMField_USE_GSL) + find_package(GSL REQUIRED) +endif (KEMField_USE_GSL) + +option (KEMField_USE_FFTW "Use FFTW" OFF) +if (KEMField_USE_FFTW) + find_package(FFTW 3.3.4 REQUIRED) +endif (KEMField_USE_FFTW) # paths kasper_module_paths( KEMField ) # module debugging kasper_module_debug() -if( KEMField_ENABLE_DEBUG ) - add_cflag( KEMField_ENABLE_DEBUG ) -endif() - -# internal dependencies: kommon -kasper_find_module( Kommon ) -add_cflag (KEMFIELD_USE_KOMMON) - -# internal dependencies: kgeobag -kasper_find_module( KGeoBag ) -add_cflag (KEMFIELD_USE_KGEOBAG) # Input files add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/data) @@ -63,9 +67,9 @@ set (SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/Source) add_subdirectory(${SOURCE}/Core) add_subdirectory(${SOURCE}/Exceptions) +add_subdirectory(${SOURCE}/IO/Streamers) add_subdirectory(${SOURCE}/IO/HashGenerator) add_subdirectory(${SOURCE}/IO/StructuredASCII) -add_subdirectory(${SOURCE}/IO/Streamers) add_subdirectory(${SOURCE}/IO/FileManipulation) add_subdirectory(${SOURCE}/Math) add_subdirectory(${SOURCE}/Math/Array) @@ -74,6 +78,7 @@ add_subdirectory(${SOURCE}/Math/VectorMath) add_subdirectory(${SOURCE}/Surfaces) add_subdirectory(${SOURCE}/BoundaryIntegrals/Core) add_subdirectory(${SOURCE}/BoundaryIntegrals/Electrostatic) +add_subdirectory(${SOURCE}/BoundaryIntegrals/Magnetostatic) add_subdirectory(${SOURCE}/LinearAlgebra/Core) add_subdirectory(${SOURCE}/LinearAlgebra/Solvers) add_subdirectory(${SOURCE}/LinearAlgebra/Preconditioners) @@ -91,11 +96,12 @@ add_subdirectory(${SOURCE}/FastMultipole/Electrostatics) add_subdirectory(${SOURCE}/FastMultipole/Interface/Extraction) add_subdirectory(${SOURCE}/FastMultipole/Interface/BoundaryIntegrals) add_subdirectory(${SOURCE}/FastMultipole/Interface/FieldSolvers) -add_subdirectory(${SOURCE}/Plugins/OpenCL) add_subdirectory(${SOURCE}/Visualization) +add_subdirectory(${SOURCE}/Plugins/OpenCL) +add_subdirectory(${SOURCE}/Plugins/PETSc) +add_subdirectory(${SOURCE}/Plugins/Root) add_subdirectory(${SOURCE}/Plugins/VTK) add_subdirectory(${SOURCE}/FastMultipole/Utility) -add_subdirectory(${SOURCE}/Plugins/PETSc) add_subdirectory(${SOURCE}/Interface/BoundaryIntegrators/Electric) add_subdirectory(${SOURCE}/Interface/ChargeDensitySolvers/Electric) add_subdirectory(${SOURCE}/Interface/FieldSolvers/Electric) @@ -105,12 +111,11 @@ add_subdirectory(${SOURCE}/Interface/Fields/Electric) add_subdirectory(${SOURCE}/Interface/KGeoBag) add_subdirectory(${SOURCE}/Plugins/VTKPart2) add_subdirectory(${SOURCE}/Bindings) -add_subdirectory(${SOURCE}/Plugins/Root) add_subdirectory(${SOURCE}/Applications/Calculation) -add_subdirectory(${SOURCE}/Applications/Test) add_subdirectory(${SOURCE}/Applications/Tools) -add_subdirectory(${SOURCE}/FastMultipole/Test) +add_subdirectory(${SOURCE}/Applications/Test) add_subdirectory(${SOURCE}/FastMultipole/Applications) +add_subdirectory(${SOURCE}/FastMultipole/Test) add_subdirectory(${SOURCE}/XML) kasper_install_module() diff --git a/KEMField/KEMFieldConfig.cmake.in b/KEMField/KEMFieldConfig.cmake.in new file mode 100644 index 000000000..3c9537588 --- /dev/null +++ b/KEMField/KEMFieldConfig.cmake.in @@ -0,0 +1,44 @@ +include(CMakeFindDependencyMacro) + +set(KEMField_USE_VTK @KEMField_USE_VTK@) +if(KEMField_USE_VTK) + find_dependency( VTK NO_MODULE ) +endif(KEMField_USE_VTK) + +set(KEMField_USE_ROOT @KEMField_USE_ROOT@) +if(KEMField_USE_ROOT) + find_dependency( ROOT CONFIG ) +endif(KEMField_USE_ROOT) + +set(KEMField_USE_GSL @KEMField_USE_GSL@) +if(KEMField_USE_GSL) + find_dependency( GSL ) +endif(KEMField_USE_GSL) + +# set(KEMField_USE_FFTW @KEMField_USE_FFTW@) +# if(KEMField_USE_FFTW) +# find_dependency( FFTW ) +# endif(KEMField_USE_FFTW) + +set(KEMField_USE_PETSc @KEMField_USE_PETSc@) +if(KEMField_USE_PETSc) + find_dependency( PETSc ) +endif(KEMField_USE_PETSc) + +set(KEMField_USE_OPENCL @KEMField_USE_OPENCL@) +if(KEMField_USE_OPENCL) + find_dependency( OpenCL ) +endif(KEMField_USE_OPENCL) + +set(KEMField_USE_MPI @KEMField_USE_MPI@) +if(KEMField_USE_MPI) + find_dependency(MPI) +endif(KEMField_USE_MPI) + +# Kasper dependencies +find_dependency( Kommon ) +find_dependency( KGeoBag ) + +if(NOT TARGET @PROJECT_NAME@::@PROJECT_NAME@) + include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +endif() diff --git a/UnitTest/ModuleConfigVersion.cmake.in b/KEMField/KEMFieldConfigVersion.cmake.in similarity index 83% rename from UnitTest/ModuleConfigVersion.cmake.in rename to KEMField/KEMFieldConfigVersion.cmake.in index 1392f662f..25f052f29 100644 --- a/UnitTest/ModuleConfigVersion.cmake.in +++ b/KEMField/KEMFieldConfigVersion.cmake.in @@ -1,7 +1,5 @@ -# $Id: ModuleConfigVersion.cmake.in 11916 2012-01-20 18:16:45Z s_voec01 $ - set(PACKAGE_VERSION "@MODULE_VERSION@") - + # Check whether the requested PACKAGE_FIND_VERSION is compatible if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") set(PACKAGE_VERSION_COMPATIBLE FALSE) diff --git a/KEMField/ModuleConfig.cmake.in b/KEMField/ModuleConfig.cmake.in deleted file mode 100644 index 5acc0074e..000000000 --- a/KEMField/ModuleConfig.cmake.in +++ /dev/null @@ -1,27 +0,0 @@ -# $Id: $ - -if(@PROJECT_NAME@_FOUND) - return() -endif() - -set(@PROJECT_NAME@_FOUND TRUE) - -# Update this section - -# The extra libraries one has to link against -set(@PROJECT_NAME@_DEPENDS @Kommon_LIBRARIES@ @Kommon_Vtk_LIBRARIES@ @ROOT_LIBRARIES@ @VTK_LIBRARIES@) -list(REMOVE_DUPLICATES @PROJECT_NAME@_DEPENDS) -# End - -set(@PROJECT_NAME@_VERSION_MAJOR @MODULE_VERSION_MAJOR@) -set(@PROJECT_NAME@_VERSION_MINOR @MODULE_VERSION_MINOR@) -set(@PROJECT_NAME@_VERSION_PATCH @MODULE_VERSION_PATCH@) -set(@PROJECT_NAME@_VERSION @MODULE_VERSION@) - -set(@PROJECT_NAME@_CFLAGS @MODULE_CFLAGS@) -set(@PROJECT_NAME@_INCLUDE_DIRS @MODULE_INCLUDE_DIRS@) -set(@PROJECT_NAME@_LIBRARIES @MODULE_TARGETS@ ) -foreach(LIB @MODULE_TARGETS@) -set(@PROJECT_NAME@_LIBRARIES_MPI "${@PROJECT_NAME@_LIBRARIES_MPI} ${LIB}_mpi") -endforeach(LIB) -mark_as_advanced(@PROJECT_NAME@_DIR) diff --git a/KEMField/ModuleConfigInstalled.cmake.in b/KEMField/ModuleConfigInstalled.cmake.in deleted file mode 100644 index 85ef2b5fa..000000000 --- a/KEMField/ModuleConfigInstalled.cmake.in +++ /dev/null @@ -1,34 +0,0 @@ -# $Id: $ - -if(@PROJECT_NAME@_FOUND) - return() -endif() - -set(@PROJECT_NAME@_FOUND TRUE) - -# Update this section - -set(@PROJECT_NAME@_DEPENDS @Kommon_LIBRARIES@ @Kommon_Vtk_LIBRARIES@ @ROOT_LIBRARIES@ @VTK_LIBRARIES@) -list(REMOVE_DUPLICATES @PROJECT_NAME@_DEPENDS) -# End - -set(@PROJECT_NAME@_VERSION_MAJOR @MODULE_VERSION_MAJOR@) -set(@PROJECT_NAME@_VERSION_MINOR @MODULE_VERSION_MINOR@) -set(@PROJECT_NAME@_VERSION_PATCH @MODULE_VERSION_PATCH@) -set(@PROJECT_NAME@_VERSION @MODULE_VERSION@) - -get_filename_component(MODULE_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) -if(EXISTS "${MODULE_CMAKE_DIR}/ModuleTargets.cmake") - include("${MODULE_CMAKE_DIR}/ModuleTargets.cmake") -elseif(NOT KASPER_TARGETS_INCLUDED) - include("${MODULE_CMAKE_DIR}/../Kasper/KasperTargets.cmake") - set(KASPER_TARGETS_INCLUDED TRUE) -endif() - -set(@PROJECT_NAME@_CFLAGS @MODULE_CFLAGS@) -set(@PROJECT_NAME@_INCLUDE_DIRS @INSTALLED_INCLUDE_DIRS@) -set(@PROJECT_NAME@_LIBRARIES @MODULE_TARGETS@ ) -set(@PROJECT_NAME@_MPI_LIBRARIES "-L@CMAKE_INSTALL_PREFIX@/lib") -foreach(LIB @MODULE_TARGETS@) -set(@PROJECT_NAME@_MPI_LIBRARIES "${@PROJECT_NAME@_MPI_LIBRARIES} -l${LIB}_mpi") -endforeach(LIB) diff --git a/KEMField/Source/Applications/Calculation/CMakeLists.txt b/KEMField/Source/Applications/Calculation/CMakeLists.txt index 6c2604397..b3110efae 100644 --- a/KEMField/Source/Applications/Calculation/CMakeLists.txt +++ b/KEMField/Source/Applications/Calculation/CMakeLists.txt @@ -1,124 +1,98 @@ # CMakeLists for KEMField/Applications/Calculation # Author: T.J. Corona, D. Hilk -kasper_include_default_dirs() - -set (APPLICATIONS_LIBS - ${ROOT_LIBRARIES} - ${GSL_LIBRARIES} - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - KEMCore - KEMHashGenerator - KEMStructuredASCII - KEMMath - KEMSurfaces - KEMIO - KEMFileManipulation - KEMElectrostaticBoundaryIntegrals - KEMElectromagnets - KEMZHGenerator - KEMZHSolver - KEMVisualization - KFMMathUtilities - KGeoBagInterface - KGeoBagMath - ) - -if (${PROJECT_NAME}_USE_ROOT) - kasper_external_include_directories( ${ROOT_INCLUDE_DIRS} ) - list (APPEND APPLICATIONS_LIBS - KEMRootPlugin - ) -endif (${PROJECT_NAME}_USE_ROOT) +option (KEMField_ENABLE_APP "Build KEMField applications" ON) +if (KEMField_ENABLE_APP) -if (${PROJECT_NAME}_USE_OPENCL) - kasper_external_include_directories( ${OPENCL_INCLUDE_DIRS} ) - list (APPEND APPLICATIONS_LIBS - KEMOpenCLPlugin + set (APPLICATIONS_LIBS + KEMFieldBindings ) -endif (${PROJECT_NAME}_USE_OPENCL) -if (${PROJECT_NAME}_USE_PETSc) - list (APPEND APPLICATIONS_LIBS - KEMPETScPlugin - ) -endif (${PROJECT_NAME}_USE_PETSc) + if (KEMField_USE_ROOT) + list (APPEND APPLICATIONS_LIBS KEMRootPlugin) + endif (KEMField_USE_ROOT) -if (${PROJECT_NAME}_USE_VTK) - list (APPEND APPLICATIONS_LIBS KEMVTKPlugin ${Kommon_Vtk_LIBRARIES} ) -endif (${PROJECT_NAME}_USE_VTK) + if (KEMField_USE_OPENCL) + list (APPEND APPLICATIONS_LIBS KEMOpenCLPlugin) + endif (KEMField_USE_OPENCL) -set_property( - SOURCE - ${CMAKE_CURRENT_SOURCE_DIR}/ComputeSphericalCapacitor.cc - APPEND PROPERTY COMPILE_DEFINITIONS DEFAULT_DATA_DIR="${${PROJECT_NAME}_CONFIG_INSTALL_DIR}" - ) + if (KEMField_USE_PETSc) + list (APPEND APPLICATIONS_LIBS KEMPETScPlugin) + endif (KEMField_USE_PETSc) -set_property( - SOURCE - ${CMAKE_CURRENT_SOURCE_DIR}/ComputeSphericalCapacitor.cc - APPEND PROPERTY COMPILE_DEFINITIONS DEFAULT_OUTPUT_DIR="${${PROJECT_NAME}_OUTPUT_INSTALL_DIR}" - ) + if (KEMField_USE_VTK) + list (APPEND APPLICATIONS_LIBS KEMVTKPlugin) + endif (KEMField_USE_VTK) -add_executable (ComputeChargeDensities - ${CMAKE_CURRENT_SOURCE_DIR}/ComputeChargeDensities.cc) -target_link_libraries (ComputeChargeDensities ${APPLICATIONS_LIBS} ) -add_executable (ComputeChargeDensitiesFromElcd33File - ${CMAKE_CURRENT_SOURCE_DIR}/ComputeChargeDensitiesFromElcd33File.cc) -target_link_libraries (ComputeChargeDensitiesFromElcd33File ${APPLICATIONS_LIBS} ) + set_property(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/ComputeSphericalCapacitor.cc + APPEND PROPERTY COMPILE_DEFINITIONS DEFAULT_DATA_DIR="${KEMField_CONFIG_INSTALL_DIR}" + ) + + set_property( SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/ComputeSphericalCapacitor.cc + APPEND PROPERTY COMPILE_DEFINITIONS DEFAULT_OUTPUT_DIR="${KEMField_OUTPUT_INSTALL_DIR}" + ) -add_executable (ComputeSphericalCapacitor - ${CMAKE_CURRENT_SOURCE_DIR}/ComputeSphericalCapacitor.cc) -target_link_libraries (ComputeSphericalCapacitor ${APPLICATIONS_LIBS} ) + add_executable (ComputeChargeDensities + ${CMAKE_CURRENT_SOURCE_DIR}/ComputeChargeDensities.cc) + target_link_libraries (ComputeChargeDensities ${APPLICATIONS_LIBS} ) + add_executable (ComputeChargeDensitiesFromElcd33File + ${CMAKE_CURRENT_SOURCE_DIR}/ComputeChargeDensitiesFromElcd33File.cc) + target_link_libraries (ComputeChargeDensitiesFromElcd33File ${APPLICATIONS_LIBS} ) + + add_executable (ComputeSphericalCapacitor + ${CMAKE_CURRENT_SOURCE_DIR}/ComputeSphericalCapacitor.cc) + target_link_libraries (ComputeSphericalCapacitor ${APPLICATIONS_LIBS} ) + + + kasper_install_executables ( + ComputeChargeDensities + ComputeChargeDensitiesFromElcd33File + ComputeSphericalCapacitor + ) -kasper_install_executables ( - ComputeChargeDensities - ComputeChargeDensitiesFromElcd33File - ComputeSphericalCapacitor - ) + # ROOT -# ROOT + if (KEMField_USE_ROOT) -if (${PROJECT_NAME}_USE_ROOT) + add_executable (AspectRatioFromKbdROOT + ${CMAKE_CURRENT_SOURCE_DIR}/AspectRatioFromKbdROOT.cc) + target_link_libraries (AspectRatioFromKbdROOT ${APPLICATIONS_LIBS} ) - add_executable (AspectRatioFromKbdROOT - ${CMAKE_CURRENT_SOURCE_DIR}/AspectRatioFromKbdROOT.cc) - target_link_libraries (AspectRatioFromKbdROOT ${APPLICATIONS_LIBS} ) + add_executable (CompareFieldsAndPotentialsROOT + ${CMAKE_CURRENT_SOURCE_DIR}/CompareFieldsAndPotentialsROOT.cc) + target_link_libraries (CompareFieldsAndPotentialsROOT ${APPLICATIONS_LIBS} ) - add_executable (CompareFieldsAndPotentialsROOT - ${CMAKE_CURRENT_SOURCE_DIR}/CompareFieldsAndPotentialsROOT.cc) - target_link_libraries (CompareFieldsAndPotentialsROOT ${APPLICATIONS_LIBS} ) + add_executable (DistanceRatioFromKbdROOT + ${CMAKE_CURRENT_SOURCE_DIR}/DistanceRatioFromKbdROOT.cc) + target_link_libraries (DistanceRatioFromKbdROOT ${APPLICATIONS_LIBS} ) - add_executable (DistanceRatioFromKbdROOT - ${CMAKE_CURRENT_SOURCE_DIR}/DistanceRatioFromKbdROOT.cc) - target_link_libraries (DistanceRatioFromKbdROOT ${APPLICATIONS_LIBS} ) + kasper_install_executables ( + AspectRatioFromKbdROOT + CompareFieldsAndPotentialsROOT + DistanceRatioFromKbdROOT + ) - kasper_install_executables ( - AspectRatioFromKbdROOT - CompareFieldsAndPotentialsROOT - DistanceRatioFromKbdROOT - ) + endif (KEMField_USE_ROOT) -endif (${PROJECT_NAME}_USE_ROOT) + #PCL Stuff -#PCL Stuff + #cmake_minimum_required(VERSION 2.8 FATAL_ERROR) -#cmake_minimum_required(VERSION 2.8 FATAL_ERROR) + #project(greedy_projection) -#project(greedy_projection) + #find_package(PCL 1.2 REQUIRED) -#find_package(PCL 1.2 REQUIRED) + #include_directories(${PCL_INCLUDE_DIRS}) + #link_directories(${PCL_LIBRARY_DIRS}) + #add_definitions(${PCL_DEFINITIONS}) -#include_directories(${PCL_INCLUDE_DIRS}) -#link_directories(${PCL_LIBRARY_DIRS}) -#add_definitions(${PCL_DEFINITIONS}) + #add_executable (greedy_projection ${CMAKE_CURRENT_SOURCE_DIR}/greedy_projection.cpp) + #target_link_libraries (greedy_projection ${PCL_LIBRARIES}) -#add_executable (greedy_projection ${CMAKE_CURRENT_SOURCE_DIR}/greedy_projection.cpp) -#target_link_libraries (greedy_projection ${PCL_LIBRARIES}) + #kasper_install_executables ( + # greedy_projection + # ) -#kasper_install_executables ( -# greedy_projection -# ) +endif (KEMField_ENABLE_APP) diff --git a/KEMField/Source/Applications/Test/CMakeLists.txt b/KEMField/Source/Applications/Test/CMakeLists.txt index 5f586a163..5b7604ed1 100644 --- a/KEMField/Source/Applications/Test/CMakeLists.txt +++ b/KEMField/Source/Applications/Test/CMakeLists.txt @@ -1,344 +1,313 @@ # CMakeLists for KEMField/Tests # Author: T.J. Corona -option (${PROJECT_NAME}_ENABLE_TEST "Build test applications" OFF) -if (${PROJECT_NAME}_ENABLE_TEST) - enable_testing () -endif (${PROJECT_NAME}_ENABLE_TEST) - -if (${PROJECT_NAME}_ENABLE_TEST) - - kasper_internal_include_directories(${${PROJECT_NAME}_INCLUDE_DIRS}) - - set (TESTS_HEADERS - include/KElectrostaticBoundaryIntegratorOptions.hh - include/TestCubatureTriangleIntegrator.hh - include/TestRWGTriangleIntegrator.hh - ) +option (KEMField_ENABLE_TEST "Build KEMField test applications" OFF) +if (KEMField_ENABLE_TEST) + enable_testing () +endif (KEMField_ENABLE_TEST) - kasper_internal_include_directories( include ) - kasper_install_headers( ${TESTS_HEADERS} ) - - set (TESTS_LIBS - ${ROOT_LIBRARIES} - ${GSL_LIBRARIES} - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - KEMCore - KEMHashGenerator - KEMStructuredASCII - KEMMath - KFMMathUtilities - KEMSurfaces - KEMIO - KEMFileManipulation - KEMElectrostaticBoundaryIntegrals - KEMElectromagnets - KEMZHGenerator - KEMZHSolver - KEMVisualization - KGeoBagInterface - ) +if (KEMField_ENABLE_TEST) - - if (${PROJECT_NAME}_USE_VTK) - list (APPEND TESTS_LIBS - ${Kommon_Vtk_LIBRARIES} - KEMVTKPlugin + set (TESTS_HEADERS + include/KElectrostaticBoundaryIntegratorOptions.hh + include/TestCubatureTriangleIntegrator.hh + include/TestRWGTriangleIntegrator.hh ) - endif (${PROJECT_NAME}_USE_VTK) - if (${PROJECT_NAME}_USE_ROOT) - find_package(ROOT REQUIRED) - kasper_external_include_directories( ${ROOT_INCLUDE_DIRS} ) - list (APPEND TESTS_LIBS - KEMRootPlugin + set (TESTS_LIBS + KGeoBagInterface + KEMCore + KEMIO + KEMFileManipulation + KEMElectrostaticBoundaryIntegrals + KEMElectromagnets + KEMLinearAlgebraPreconditioner + KEMZHSolver + KEMVisualization ) - endif (${PROJECT_NAME}_USE_ROOT) - if (${PROJECT_NAME}_USE_OPENCL) - find_package(OpenCL REQUIRED) - kasper_external_include_directories( ${OPENCL_INCLUDE_DIRS} ) - list (APPEND TESTS_LIBS - KEMOpenCLPlugin - ) - endif (${PROJECT_NAME}_USE_OPENCL) + if (KEMField_USE_VTK) + list (APPEND TESTS_LIBS KEMVTKPlugin) + endif (KEMField_USE_VTK) - if (${PROJECT_NAME}_USE_PETSc) - list (APPEND TESTS_LIBS - KEMPETScPlugin - ) - endif (${PROJECT_NAME}_USE_PETSc) - - if (${PROJECT_NAME}_USE_VTK) - list (APPEND TESTS_LIBS - ${VTK_LIBRARIES}) - endif (${PROJECT_NAME}_USE_VTK) - - add_executable (TestElectromagnets - ${CMAKE_CURRENT_SOURCE_DIR}/TestElectromagnets.cc) - target_link_libraries (TestElectromagnets ${TESTS_LIBS} ) - - add_executable (TestElectromagnetViewer - ${CMAKE_CURRENT_SOURCE_DIR}/TestElectromagnetViewer.cc) - target_link_libraries (TestElectromagnetViewer ${TESTS_LIBS} ) - - add_executable (TestDiskCapacitance - ${CMAKE_CURRENT_SOURCE_DIR}/TestDiskCapacitance.cc) - target_link_libraries (TestDiskCapacitance ${TESTS_LIBS} ) - - add_executable (TestEMFileInterface - ${CMAKE_CURRENT_SOURCE_DIR}/TestEMFileInterface.cc) - target_link_libraries (TestEMFileInterface ${TESTS_LIBS} ) - - add_executable (TestGeometry - ${CMAKE_CURRENT_SOURCE_DIR}/TestGeometry.cc) - target_link_libraries (TestGeometry ${TESTS_LIBS} ) - - add_executable (TestAnisotropicPoisson - ${CMAKE_CURRENT_SOURCE_DIR}/TestAnisotropicPoisson.cc) - target_link_libraries (TestAnisotropicPoisson ${TESTS_LIBS} ) - - add_executable (TestCubatureSpeedStandAlone - ${CMAKE_CURRENT_SOURCE_DIR}/TestCubatureSpeedStandAlone.cc) - target_link_libraries (TestCubatureSpeedStandAlone ${TESTS_LIBS} ) - - add_executable (TestIntegratorFunctionality - ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorFunctionality.cc) - target_link_libraries (TestIntegratorFunctionality ${TESTS_LIBS} ) - - add_executable (TestIntegratorSpeed - ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorSpeed.cc) - target_link_libraries (TestIntegratorSpeed ${TESTS_LIBS} ) - - add_executable (TestIntegratorSpeedWithKbdInput - ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorSpeedWithKbdInput.cc) - target_link_libraries (TestIntegratorSpeedWithKbdInput ${TESTS_LIBS} ) - - add_executable (TestIntegratorRWG - ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorRWG.cc) - target_link_libraries (TestIntegratorRWG ${TESTS_LIBS} ) - - add_executable (TestIntegratorRWGAccuracy - ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorRWGAccuracy.cc) - target_link_libraries (TestIntegratorRWGAccuracy ${TESTS_LIBS} ) - - add_executable (TestInverseDistance - ${CMAKE_CURRENT_SOURCE_DIR}/TestInverseDistance.cc) - target_link_libraries (TestInverseDistance ${TESTS_LIBS} ) - - add_executable (TestSVDSolver - ${CMAKE_CURRENT_SOURCE_DIR}/TestSVDSolver.cc) - target_link_libraries (TestSVDSolver ${TESTS_LIBS} ) - - add_executable (TestBinaryTruncation - ${CMAKE_CURRENT_SOURCE_DIR}/TestBinaryTruncation.cc) - target_link_libraries (TestBinaryTruncation ${TESTS_LIBS} ) - - add_executable (TestTriangles - ${CMAKE_CURRENT_SOURCE_DIR}/TestTriangles.cc) - target_link_libraries (TestTriangles ${TESTS_LIBS} ) - - add_executable (TestTypelists - ${CMAKE_CURRENT_SOURCE_DIR}/TestTypelists.cc) - target_link_libraries (TestTypelists ${TESTS_LIBS} ) - - add_executable (TestVisitor - ${CMAKE_CURRENT_SOURCE_DIR}/TestVisitor.cc) - target_link_libraries (TestVisitor ${TESTS_LIBS} ) - - add_executable (TestZonalHarmonics - ${CMAKE_CURRENT_SOURCE_DIR}/TestZonalHarmonics.cc) - target_link_libraries (TestZonalHarmonics ${TESTS_LIBS} ) + if (KEMField_USE_ROOT) + find_package(ROOT REQUIRED) + list (APPEND TESTS_LIBS KEMRootPlugin) + endif (KEMField_USE_ROOT) + + if (KEMField_USE_OPENCL) + find_package(OpenCL REQUIRED) + list (APPEND TESTS_LIBS KEMOpenCLPlugin) + endif (KEMField_USE_OPENCL) + + if (KEMField_USE_PETSc) + list (APPEND TESTS_LIBS KEMPETScPlugin) + endif (KEMField_USE_PETSc) + + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) + + add_executable (TestElectromagnets + ${CMAKE_CURRENT_SOURCE_DIR}/TestElectromagnets.cc) + target_link_libraries (TestElectromagnets ${TESTS_LIBS} ) + + add_executable (TestElectromagnetViewer + ${CMAKE_CURRENT_SOURCE_DIR}/TestElectromagnetViewer.cc) + target_link_libraries (TestElectromagnetViewer ${TESTS_LIBS} ) + + add_executable (TestDiskCapacitance + ${CMAKE_CURRENT_SOURCE_DIR}/TestDiskCapacitance.cc) + target_link_libraries (TestDiskCapacitance ${TESTS_LIBS} ) + + add_executable (TestEMFileInterface + ${CMAKE_CURRENT_SOURCE_DIR}/TestEMFileInterface.cc) + target_link_libraries (TestEMFileInterface ${TESTS_LIBS} ) + + add_executable (TestGeometry + ${CMAKE_CURRENT_SOURCE_DIR}/TestGeometry.cc) + target_link_libraries (TestGeometry ${TESTS_LIBS} ) + + add_executable (TestAnisotropicPoisson + ${CMAKE_CURRENT_SOURCE_DIR}/TestAnisotropicPoisson.cc) + target_link_libraries (TestAnisotropicPoisson ${TESTS_LIBS} ) + + add_executable (TestCubatureSpeedStandAlone + ${CMAKE_CURRENT_SOURCE_DIR}/TestCubatureSpeedStandAlone.cc) + target_link_libraries (TestCubatureSpeedStandAlone ${TESTS_LIBS} ) + + add_executable (TestIntegratorFunctionality + ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorFunctionality.cc) + target_link_libraries (TestIntegratorFunctionality ${TESTS_LIBS} ) + + add_executable (TestIntegratorSpeed + ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorSpeed.cc) + target_link_libraries (TestIntegratorSpeed ${TESTS_LIBS} ) + + add_executable (TestIntegratorSpeedWithKbdInput + ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorSpeedWithKbdInput.cc) + target_link_libraries (TestIntegratorSpeedWithKbdInput ${TESTS_LIBS} ) + + add_executable (TestIntegratorRWG + ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorRWG.cc) + target_link_libraries (TestIntegratorRWG ${TESTS_LIBS} ) + + add_executable (TestIntegratorRWGAccuracy + ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorRWGAccuracy.cc) + target_link_libraries (TestIntegratorRWGAccuracy ${TESTS_LIBS} ) + + add_executable (TestInverseDistance + ${CMAKE_CURRENT_SOURCE_DIR}/TestInverseDistance.cc) + target_link_libraries (TestInverseDistance ${TESTS_LIBS} ) + + add_executable (TestSVDSolver + ${CMAKE_CURRENT_SOURCE_DIR}/TestSVDSolver.cc) + target_link_libraries (TestSVDSolver ${TESTS_LIBS} ) + + add_executable (TestBinaryTruncation + ${CMAKE_CURRENT_SOURCE_DIR}/TestBinaryTruncation.cc) + target_link_libraries (TestBinaryTruncation ${TESTS_LIBS} ) + + add_executable (TestTriangles + ${CMAKE_CURRENT_SOURCE_DIR}/TestTriangles.cc) + target_link_libraries (TestTriangles ${TESTS_LIBS} ) + + add_executable (TestTypelists + ${CMAKE_CURRENT_SOURCE_DIR}/TestTypelists.cc) + target_link_libraries (TestTypelists ${TESTS_LIBS} ) + + add_executable (TestVisitor + ${CMAKE_CURRENT_SOURCE_DIR}/TestVisitor.cc) + target_link_libraries (TestVisitor ${TESTS_LIBS} ) + + add_executable (TestZonalHarmonics + ${CMAKE_CURRENT_SOURCE_DIR}/TestZonalHarmonics.cc) + target_link_libraries (TestZonalHarmonics ${TESTS_LIBS} ) add_executable (TestCubeCapacitance - ${CMAKE_CURRENT_SOURCE_DIR}/TestCubeCapacitance.cc) + ${CMAKE_CURRENT_SOURCE_DIR}/TestCubeCapacitance.cc) target_link_libraries (TestCubeCapacitance ${TESTS_LIBS}) add_executable (TestSphereCapacitance - ${CMAKE_CURRENT_SOURCE_DIR}/TestSphereCapacitance.cc) + ${CMAKE_CURRENT_SOURCE_DIR}/TestSphereCapacitance.cc) target_link_libraries (TestSphereCapacitance ${TESTS_LIBS}) - add_executable (TestSuperposition - ${CMAKE_CURRENT_SOURCE_DIR}/TestSuperposition.cc) - target_link_libraries (TestSuperposition ${TESTS_LIBS} ) + add_executable (TestSuperposition + ${CMAKE_CURRENT_SOURCE_DIR}/TestSuperposition.cc) + target_link_libraries (TestSuperposition ${TESTS_LIBS} ) - add_executable (TestSymmetryGroups - ${CMAKE_CURRENT_SOURCE_DIR}/TestSymmetryGroups.cc) - target_link_libraries (TestSymmetryGroups ${TESTS_LIBS} ) + add_executable (TestSymmetryGroups + ${CMAKE_CURRENT_SOURCE_DIR}/TestSymmetryGroups.cc) + target_link_libraries (TestSymmetryGroups ${TESTS_LIBS} ) # add_executable (TestSphericalImageCharge # ${CMAKE_CURRENT_SOURCE_DIR}/TestSphericalImageCharge.cc) # target_link_libraries (TestSphericalImageCharge ${TESTS_LIBS}) - kasper_install_executables ( - TestCubatureSpeedStandAlone - TestDiskCapacitance - TestElectromagnets - TestElectromagnetViewer - TestEMFileInterface - TestGeometry - TestAnisotropicPoisson - TestIntegratorFunctionality - TestIntegratorSpeed - TestIntegratorSpeedWithKbdInput - TestIntegratorRWG - TestIntegratorRWGAccuracy - TestInverseDistance - TestSVDSolver - TestBinaryTruncation - TestTriangles - TestTypelists - TestVisitor - TestZonalHarmonics - TestCubeCapacitance - TestSphereCapacitance - TestSuperposition - TestSymmetryGroups - # TestSphericalImageCharge + kasper_install_executables ( + TestCubatureSpeedStandAlone + TestDiskCapacitance + TestElectromagnets + TestElectromagnetViewer + TestEMFileInterface + TestGeometry + TestAnisotropicPoisson + TestIntegratorFunctionality + TestIntegratorSpeed + TestIntegratorSpeedWithKbdInput + TestIntegratorRWG + TestIntegratorRWGAccuracy + TestInverseDistance + TestSVDSolver + TestBinaryTruncation + TestTriangles + TestTypelists + TestVisitor + TestZonalHarmonics + TestCubeCapacitance + TestSphereCapacitance + TestSuperposition + TestSymmetryGroups + # TestSphericalImageCharge ) -############ -### ROOT ### -############ - - if (${PROJECT_NAME}_USE_ROOT) - - add_executable (TestDielectrics - ${CMAKE_CURRENT_SOURCE_DIR}/TestDielectrics.cc) - target_link_libraries (TestDielectrics ${TESTS_LIBS} ) - - add_executable (TestIntegratorDistRatioLineSegmentROOT - ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorDistRatioLineSegmentROOT.cc) - target_link_libraries (TestIntegratorDistRatioLineSegmentROOT ${TESTS_LIBS} ) - - add_executable (TestIntegratorDistRatioRectangleROOT - ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorDistRatioRectangleROOT.cc) - target_link_libraries (TestIntegratorDistRatioRectangleROOT ${TESTS_LIBS} ) - - add_executable (TestIntegratorDistRatioTriangleROOT - ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorDistRatioTriangleROOT.cc) - target_link_libraries (TestIntegratorDistRatioTriangleROOT ${TESTS_LIBS} ) - - add_executable (TestVectorTypes - ${CMAKE_CURRENT_SOURCE_DIR}/TestVectorTypes.cc) - target_link_libraries (TestVectorTypes ${TESTS_LIBS} ) - - kasper_install_executables ( - TestDielectrics - TestIntegratorDistRatioLineSegmentROOT - TestIntegratorDistRatioRectangleROOT - TestIntegratorDistRatioTriangleROOT - TestVectorTypes - ) - - endif (${PROJECT_NAME}_USE_ROOT) - -################ -### KMessage ### -################ - -# if (${PROJECT_NAME}_USE_KMESSAGE) + ############ + ### ROOT ### + ############ - add_executable (TestKMessageInterface - ${CMAKE_CURRENT_SOURCE_DIR}/TestKMessageInterface.cc) - target_link_libraries (TestKMessageInterface ${TESTS_LIBS}) + if (KEMField_USE_ROOT) + + add_executable (TestDielectrics + ${CMAKE_CURRENT_SOURCE_DIR}/TestDielectrics.cc) + target_link_libraries (TestDielectrics ${TESTS_LIBS} ) + + add_executable (TestIntegratorDistRatioLineSegmentROOT + ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorDistRatioLineSegmentROOT.cc) + target_link_libraries (TestIntegratorDistRatioLineSegmentROOT ${TESTS_LIBS} ) + + add_executable (TestIntegratorDistRatioRectangleROOT + ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorDistRatioRectangleROOT.cc) + target_link_libraries (TestIntegratorDistRatioRectangleROOT ${TESTS_LIBS} ) - kasper_install_executables ( - TestKMessageInterface + add_executable (TestIntegratorDistRatioTriangleROOT + ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorDistRatioTriangleROOT.cc) + target_link_libraries (TestIntegratorDistRatioTriangleROOT ${TESTS_LIBS} ) + + add_executable (TestVectorTypes + ${CMAKE_CURRENT_SOURCE_DIR}/TestVectorTypes.cc) + target_link_libraries (TestVectorTypes ${TESTS_LIBS} ) + + kasper_install_executables ( + TestDielectrics + TestIntegratorDistRatioLineSegmentROOT + TestIntegratorDistRatioRectangleROOT + TestIntegratorDistRatioTriangleROOT + TestVectorTypes ) -# endif (${PROJECT_NAME}_USE_KMESSAGE) - -#################### -### OpenCL + MPI ### -#################### - -# if (${PROJECT_NAME}_USE_OPENCL AND ${PROJECT_NAME}_USE_MPI) -# -# add_executable (TestOpenCL -# ${CMAKE_CURRENT_SOURCE_DIR}/TestOpenCL.cc) -# target_link_libraries (TestOpenCL ${OPENCL_LIBRARIES} ) - -# kasper_install_executables ( -# TestOpenCL -# ) - -# endif (${PROJECT_NAME}_USE_OPENCL AND ${PROJECT_NAME}_USE_MPI) - -############## -### OpenCL ### -############## - - if (${PROJECT_NAME}_USE_OPENCL) - - if (${PROJECT_NAME}_USE_ROOT) - add_executable (TestIntegratorTriangleROOTOpenCL - ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorTriangleROOTOpenCL.cc) - target_link_libraries (TestIntegratorTriangleROOTOpenCL ${OPENCL_LIBRARIES} ${TESTS_LIBS} ) - - add_executable (TestIntegratorRectangleROOTOpenCL - ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorRectangleROOTOpenCL.cc) - target_link_libraries (TestIntegratorRectangleROOTOpenCL ${OPENCL_LIBRARIES} ${TESTS_LIBS} ) - - add_executable (TestIntegratorLineSegmentROOTOpenCL - ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorLineSegmentROOTOpenCL.cc) - target_link_libraries (TestIntegratorLineSegmentROOTOpenCL ${OPENCL_LIBRARIES} ${TESTS_LIBS} ) - + endif (KEMField_USE_ROOT) + + ################ + ### KMessage ### + ################ + + #if (KEMField_USE_KMESSAGE) + + add_executable (TestKMessageInterface + ${CMAKE_CURRENT_SOURCE_DIR}/TestKMessageInterface.cc) + target_link_libraries (TestKMessageInterface ${TESTS_LIBS}) + kasper_install_executables ( - TestIntegratorTriangleROOTOpenCL - TestIntegratorRectangleROOTOpenCL - TestIntegratorLineSegmentROOTOpenCL + TestKMessageInterface ) - - endif (${PROJECT_NAME}_USE_ROOT) - add_executable (TestOpenCLPlugin - ${CMAKE_CURRENT_SOURCE_DIR}/TestOpenCLPlugin.cc) - target_link_libraries (TestOpenCLPlugin ${OPENCL_LIBRARIES} ${TESTS_LIBS} ) - - add_executable (TestIntegratorFunctionalityOpenCL - ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorFunctionalityOpenCL.cc) - target_link_libraries (TestIntegratorFunctionalityOpenCL ${OPENCL_LIBRARIES} ${TESTS_LIBS} ) + #endif (KEMField_USE_KMESSAGE) - kasper_install_executables ( - TestIntegratorFunctionalityOpenCL - TestOpenCLPlugin - ) + #################### + ### OpenCL + MPI ### + #################### - endif (${PROJECT_NAME}_USE_OPENCL) + if (KEMField_USE_OPENCL AND KEMField_USE_MPI) + # add_executable (TestOpenCL + # ${CMAKE_CURRENT_SOURCE_DIR}/TestOpenCL.cc) + # target_link_libraries (TestOpenCL ${TESTS_LIBS} ) -############# -### PETSc ### -############# + # kasper_install_executables ( + # TestOpenCL + # ) - if (${PROJECT_NAME}_USE_PETSc) + endif (KEMField_USE_OPENCL AND KEMField_USE_MPI) -set_property( - SOURCE - ${CMAKE_CURRENT_SOURCE_DIR}/TestPETSc.cc - APPEND PROPERTY COMPILE_DEFINITIONS DEFAULT_DATA_DIR="${DATA_INSTALL_DIR}/${${PROJECT_NAME}_DATA_DIR}" -) + ############## + ### OpenCL ### + ############## - add_executable (TestPETSc - ${CMAKE_CURRENT_SOURCE_DIR}/TestPETSc.cc) - target_link_libraries (TestPETSc ${TESTS_LIBS} ${PETSC_LIBRARY}) + if (KEMField_USE_OPENCL) - add_executable (TestPETSc1 - ${CMAKE_CURRENT_SOURCE_DIR}/TestPETSc1.cc) - target_link_libraries (TestPETSc1 ${TESTS_LIBS} ${PETSC_LIBRARY}) + if (KEMField_USE_ROOT) - add_executable (TestPETSc2 - ${CMAKE_CURRENT_SOURCE_DIR}/TestPETSc2.cc) - target_link_libraries (TestPETSc2 ${TESTS_LIBS} ${PETSC_LIBRARY}) + add_executable (TestIntegratorTriangleROOTOpenCL + ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorTriangleROOTOpenCL.cc) + target_link_libraries (TestIntegratorTriangleROOTOpenCL ${TESTS_LIBS} ) - kasper_install_executables ( - TestPETSc - TestPETSc1 - TestPETSc2 - ) + add_executable (TestIntegratorRectangleROOTOpenCL + ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorRectangleROOTOpenCL.cc) + target_link_libraries (TestIntegratorRectangleROOTOpenCL ${TESTS_LIBS} ) + + add_executable (TestIntegratorLineSegmentROOTOpenCL + ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorLineSegmentROOTOpenCL.cc) + target_link_libraries (TestIntegratorLineSegmentROOTOpenCL ${TESTS_LIBS} ) + + kasper_install_executables ( + TestIntegratorTriangleROOTOpenCL + TestIntegratorRectangleROOTOpenCL + TestIntegratorLineSegmentROOTOpenCL + ) + + endif (KEMField_USE_ROOT) + + add_executable (TestOpenCLPlugin + ${CMAKE_CURRENT_SOURCE_DIR}/TestOpenCLPlugin.cc) + target_link_libraries (TestOpenCLPlugin ${TESTS_LIBS} ) + + add_executable (TestIntegratorFunctionalityOpenCL + ${CMAKE_CURRENT_SOURCE_DIR}/TestIntegratorFunctionalityOpenCL.cc) + target_link_libraries (TestIntegratorFunctionalityOpenCL ${TESTS_LIBS} ) + + kasper_install_executables ( + TestIntegratorFunctionalityOpenCL + TestOpenCLPlugin + ) + + endif (KEMField_USE_OPENCL) + + ############# + ### PETSc ### + ############# + + if (KEMField_USE_PETSc) + + set_property(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/TestPETSc.cc + APPEND PROPERTY COMPILE_DEFINITIONS DEFAULT_DATA_DIR="${DATA_INSTALL_DIR}/${KEMField_DATA_DIR}" + ) + + add_executable (TestPETSc + ${CMAKE_CURRENT_SOURCE_DIR}/TestPETSc.cc) + target_link_libraries (TestPETSc ${TESTS_LIBS}) + + add_executable (TestPETSc1 + ${CMAKE_CURRENT_SOURCE_DIR}/TestPETSc1.cc) + target_link_libraries (TestPETSc1 ${TESTS_LIBS}) + + add_executable (TestPETSc2 + ${CMAKE_CURRENT_SOURCE_DIR}/TestPETSc2.cc) + target_link_libraries (TestPETSc2 ${TESTS_LIBS}) + + kasper_install_executables ( + TestPETSc + TestPETSc1 + TestPETSc2 + ) - endif (${PROJECT_NAME}_USE_PETSc) + endif (KEMField_USE_PETSc) -endif (${PROJECT_NAME}_ENABLE_TEST) +endif (KEMField_ENABLE_TEST) diff --git a/KEMField/Source/Applications/Test/TestCubeCapacitance.cc b/KEMField/Source/Applications/Test/TestCubeCapacitance.cc index 3d7bb590e..8a1c80333 100644 --- a/KEMField/Source/Applications/Test/TestCubeCapacitance.cc +++ b/KEMField/Source/Applications/Test/TestCubeCapacitance.cc @@ -1,4 +1,4 @@ -#include "../Test/include/KElectrostaticBoundaryIntegratorOptions.hh" +#include "KElectrostaticBoundaryIntegratorOptions.hh" #include "KBinaryDataStreamer.hh" #include "KBoundaryIntegralMatrix.hh" #include "KBoundaryIntegralSolutionVector.hh" diff --git a/KEMField/Source/Applications/Test/TestDiskCapacitance.cc b/KEMField/Source/Applications/Test/TestDiskCapacitance.cc index 37c0b7a8a..df5b0151c 100644 --- a/KEMField/Source/Applications/Test/TestDiskCapacitance.cc +++ b/KEMField/Source/Applications/Test/TestDiskCapacitance.cc @@ -1,4 +1,4 @@ -#include "../Test/include/KElectrostaticBoundaryIntegratorOptions.hh" +#include "KElectrostaticBoundaryIntegratorOptions.hh" #include "KBoundaryIntegralMatrix.hh" #include "KBoundaryIntegralSolutionVector.hh" #include "KBoundaryIntegralVector.hh" diff --git a/KEMField/Source/Applications/Test/TestOpenCL.cc b/KEMField/Source/Applications/Test/TestOpenCL.cc index be082594f..73018b77a 100644 --- a/KEMField/Source/Applications/Test/TestOpenCL.cc +++ b/KEMField/Source/Applications/Test/TestOpenCL.cc @@ -9,7 +9,7 @@ #include #include -#define CL_HPP_NO_STD_VECTOR // Use cl::vector instead of STL version +//#define CL_HPP_NO_STD_VECTOR // Use cl::vector instead of STL version #define CL_HPP_ENABLE_EXCEPTIONS #if defined __APPLE__ diff --git a/KEMField/Source/Applications/Test/TestSphereCapacitance.cc b/KEMField/Source/Applications/Test/TestSphereCapacitance.cc index ce3f55be0..16cfea9c3 100644 --- a/KEMField/Source/Applications/Test/TestSphereCapacitance.cc +++ b/KEMField/Source/Applications/Test/TestSphereCapacitance.cc @@ -1,4 +1,4 @@ -#include "../Test/include/KElectrostaticBoundaryIntegratorOptions.hh" +#include "KElectrostaticBoundaryIntegratorOptions.hh" #include "KBoundaryIntegralMatrix.hh" #include "KBoundaryIntegralSolutionVector.hh" #include "KBoundaryIntegralVector.hh" diff --git a/KEMField/Source/Applications/Tools/CMakeLists.txt b/KEMField/Source/Applications/Tools/CMakeLists.txt index 634aeb0da..36eea7a37 100644 --- a/KEMField/Source/Applications/Tools/CMakeLists.txt +++ b/KEMField/Source/Applications/Tools/CMakeLists.txt @@ -1,119 +1,97 @@ # CMakeLists for KEMField/Applications/Tools # Author: T.J. Corona, D. Hilk -kasper_include_default_dirs() - -set (APPLICATIONS_LIBS - ${ROOT_LIBRARIES} - ${GSL_LIBRARIES} - ${Kommon_LIBRRIES} - ${KGeoBag_LIBRRIES} - KEMCore - KEMHashGenerator - KEMStructuredASCII - KEMMath - KEMSurfaces - KEMIO - KEMFileManipulation - KEMElectrostaticBoundaryIntegrals - KEMElectromagnets - KEMZHGenerator - KEMZHSolver - KEMVisualization - KFMMathUtilities - KGeoBagInterface - ) - -if (${PROJECT_NAME}_USE_ROOT) - kasper_external_include_directories( ${ROOT_INCLUDE_DIRS} ) - list (APPEND APPLICATIONS_LIBS - KEMRootPlugin - ) -endif (${PROJECT_NAME}_USE_ROOT) +option (KEMField_ENABLE_APP "Build KEMField applications" ON) +if (KEMField_ENABLE_APP) -if (${PROJECT_NAME}_USE_OPENCL) - kasper_external_include_directories( ${OPENCL_INCLUDE_DIRS} ) - list (APPEND APPLICATIONS_LIBS - KEMOpenCLPlugin + set (APPLICATIONS_LIBS + KEMFieldBindings ) -endif (${PROJECT_NAME}_USE_OPENCL) -if (${PROJECT_NAME}_USE_PETSc) - list (APPEND APPLICATIONS_LIBS - KEMPETScPlugin + if (KEMField_USE_ROOT) + list (APPEND APPLICATIONS_LIBS KEMRootPlugin) + endif (KEMField_USE_ROOT) + + if (KEMField_USE_OPENCL) + list (APPEND APPLICATIONS_LIBS KEMOpenCLPlugin) + endif (KEMField_USE_OPENCL) + + if (KEMField_USE_PETSc) + list (APPEND APPLICATIONS_LIBS KEMPETScPlugin) + endif (KEMField_USE_PETSc) + + if (KEMField_USE_VTK) + list (APPEND APPLICATIONS_LIBS KEMVTKPlugin) + endif (KEMField_USE_VTK) + + add_executable (KdbConverter + ${CMAKE_CURRENT_SOURCE_DIR}/KdbConverter.cc) + target_link_libraries (KdbConverter ${APPLICATIONS_LIBS} ) + + add_executable (TransferEMElement + ${CMAKE_CURRENT_SOURCE_DIR}/TransferEMElement.cc) + target_link_libraries (TransferEMElement ${APPLICATIONS_LIBS} ) + + add_executable (HashEMGeometry + ${CMAKE_CURRENT_SOURCE_DIR}/HashEMGeometry.cc) + target_link_libraries (HashEMGeometry ${APPLICATIONS_LIBS} ) + + add_executable (InspectEMFile + ${CMAKE_CURRENT_SOURCE_DIR}/InspectEMFile.cc) + target_link_libraries (InspectEMFile ${APPLICATIONS_LIBS} ) + + add_executable (WriteKbdToAscii + ${CMAKE_CURRENT_SOURCE_DIR}/WriteKbdToAscii.cc) + target_link_libraries (WriteKbdToAscii ${APPLICATIONS_LIBS} ) + + add_executable (WriteAsciiToPCD + ${CMAKE_CURRENT_SOURCE_DIR}/WriteAsciiToPCD.cc) + target_link_libraries (WriteAsciiToPCD ${APPLICATIONS_LIBS} ) + + kasper_install_executables ( + KdbConverter + TransferEMElement + HashEMGeometry + InspectEMFile + WriteKbdToAscii + WriteAsciiToPCD ) -endif (${PROJECT_NAME}_USE_PETSc) - -if (${PROJECT_NAME}_USE_VTK) - list (APPEND APPLICATIONS_LIBS KEMVTKPlugin ${Kommon_Vtk_LIBRARIES} ) -endif (${PROJECT_NAME}_USE_VTK) - -add_executable (KdbConverter - ${CMAKE_CURRENT_SOURCE_DIR}/KdbConverter.cc) -target_link_libraries (KdbConverter ${APPLICATIONS_LIBS} ) - -add_executable (TransferEMElement - ${CMAKE_CURRENT_SOURCE_DIR}/TransferEMElement.cc) -target_link_libraries (TransferEMElement ${APPLICATIONS_LIBS} ) - -add_executable (HashEMGeometry - ${CMAKE_CURRENT_SOURCE_DIR}/HashEMGeometry.cc) -target_link_libraries (HashEMGeometry ${APPLICATIONS_LIBS} ) -add_executable (InspectEMFile - ${CMAKE_CURRENT_SOURCE_DIR}/InspectEMFile.cc) -target_link_libraries (InspectEMFile ${APPLICATIONS_LIBS} ) + # VTK -add_executable (WriteKbdToAscii - ${CMAKE_CURRENT_SOURCE_DIR}/WriteKbdToAscii.cc) -target_link_libraries (WriteKbdToAscii ${APPLICATIONS_LIBS} ) + if (KEMField_USE_VTK) -add_executable (WriteAsciiToPCD - ${CMAKE_CURRENT_SOURCE_DIR}/WriteAsciiToPCD.cc) -target_link_libraries (WriteAsciiToPCD ${APPLICATIONS_LIBS} ) + add_executable (VisualizeEMGeometry + ${CMAKE_CURRENT_SOURCE_DIR}/VisualizeEMGeometry.cc) + target_link_libraries (VisualizeEMGeometry ${APPLICATIONS_LIBS} ) -kasper_install_executables ( - KdbConverter - TransferEMElement - HashEMGeometry - InspectEMFile - WriteKbdToAscii - WriteAsciiToPCD -) + kasper_install_executables ( + VisualizeEMGeometry + ) -# VTK - -if (${PROJECT_NAME}_USE_VTK) - - add_executable (VisualizeEMGeometry - ${CMAKE_CURRENT_SOURCE_DIR}/VisualizeEMGeometry.cc) - target_link_libraries (VisualizeEMGeometry ${APPLICATIONS_LIBS} ) - - kasper_install_executables ( - VisualizeEMGeometry - ) + install (DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ApplicationFiles + DESTINATION ${KEMField_CONFIG_INSTALL_DIR} + PATTERN "*.gitignore" EXCLUDE + ) -install (DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ApplicationFiles - DESTINATION ${${PROJECT_NAME}_CONFIG_INSTALL_DIR} - PATTERN "*.gitignore" EXCLUDE -) + endif (KEMField_USE_VTK) -endif (${PROJECT_NAME}_USE_VTK) + #PCL Stuff + #cmake_minimum_required(VERSION 2.8 FATAL_ERROR) -#PCL Stuff -#cmake_minimum_required(VERSION 2.8 FATAL_ERROR) + #project(greedy_projection) -#project(greedy_projection) + #find_package(PCL 1.2 REQUIRED) -#find_package(PCL 1.2 REQUIRED) + #include_directories(${PCL_INCLUDE_DIRS}) + #link_directories(${PCL_LIBRARY_DIRS}) + #add_definitions(${PCL_DEFINITIONS}) -#include_directories(${PCL_INCLUDE_DIRS}) -#link_directories(${PCL_LIBRARY_DIRS}) -#add_definitions(${PCL_DEFINITIONS}) + #add_executable (greedy_projection ${CMAKE_CURRENT_SOURCE_DIR}/greedy_projection.cpp) + #target_link_libraries (greedy_projection ${PCL_LIBRARIES}) -#add_executable (greedy_projection ${CMAKE_CURRENT_SOURCE_DIR}/greedy_projection.cpp) -#target_link_libraries (greedy_projection ${PCL_LIBRARIES}) + #kasper_install_executables ( + # greedy_projection + # ) -#kasper_install_executables ( -# greedy_projection -# ) +endif (KEMField_ENABLE_APP) diff --git a/KEMField/Source/Bindings/CMakeLists.txt b/KEMField/Source/Bindings/CMakeLists.txt index 3d499219c..3944d89db 100644 --- a/KEMField/Source/Bindings/CMakeLists.txt +++ b/KEMField/Source/Bindings/CMakeLists.txt @@ -1,20 +1,7 @@ # CMakeLists for KEMField/Source/Bindings # W. Gosda -#${PROJECT_NAME}_USE_KOMMON is defined in Core/CMakeLists.txt - -# Bindings need to be linked against Kommon, KMessage and KGeoBag -add_cflag (KEMFIELD_USE_KOMMON_BINDINGS) - - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Utilities/include) - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Fields/Electric/include) - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Fields/Magnetic/include) - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/FieldSolvers/Electric/include) - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ChargeDensitySolvers/Electric/include) - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/FieldSolvers/Magnetic/include) - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/KGeoBag/include) - - set (KEMFIELD_BINDINGS_HEADERFILES +set (KEMFIELD_BINDINGS_HEADERFILES # ${CMAKE_CURRENT_SOURCE_DIR}/Utilities/include/KEMToolbox.hh ${CMAKE_CURRENT_SOURCE_DIR}/Utilities/include/KEMToolboxBuilder.hh ${CMAKE_CURRENT_SOURCE_DIR}/Utilities/include/KEMBindingsMessage.hh @@ -56,9 +43,9 @@ add_cflag (KEMFIELD_USE_KOMMON_BINDINGS) ${CMAKE_CURRENT_SOURCE_DIR}/Fields/Electric/include/KElectrostaticPotentialmapBuilder.hh ${CMAKE_CURRENT_SOURCE_DIR}/Fields/Magnetic/include/KMagnetostaticFieldmapBuilder.hh ${CMAKE_CURRENT_SOURCE_DIR}/Fields/Magnetic/include/KMagnetostaticConstantFieldBuilder.hh - ) +) - set (KEMFIELD_BINDINGS_SOURCEFILES +set (KEMFIELD_BINDINGS_SOURCEFILES # ${CMAKE_CURRENT_SOURCE_DIR}/Utilities/src/KEMToolbox.cc ${CMAKE_CURRENT_SOURCE_DIR}/Utilities/src/KEMToolboxBuilder.cc ${CMAKE_CURRENT_SOURCE_DIR}/Utilities/src/KEMBindingsMessage.cc @@ -97,30 +84,42 @@ add_cflag (KEMFIELD_USE_KOMMON_BINDINGS) ${CMAKE_CURRENT_SOURCE_DIR}/Fields/Electric/src/KElectrostaticPotentialmapBuilder.cc ${CMAKE_CURRENT_SOURCE_DIR}/Fields/Magnetic/src/KMagnetostaticFieldmapBuilder.cc ${CMAKE_CURRENT_SOURCE_DIR}/Fields/Magnetic/src/KMagnetostaticConstantFieldBuilder.cc +) + +if (KEMField_USE_VTK) + list (APPEND KEMFIELD_BINDINGS_HEADERFILES + ${CMAKE_CURRENT_SOURCE_DIR}/FieldSolvers/Electric/include/KFMVTKElectrostaticTreeViewerBuilder.hh + ) + list (APPEND KEMFIELD_BINDINGS_SOURCEFILES + ${CMAKE_CURRENT_SOURCE_DIR}/FieldSolvers/Electric/src/KFMVTKElectrostaticTreeViewerBuilder.cc ) +endif (KEMField_USE_VTK) + +add_library (KEMFieldBindings SHARED + ${KEMFIELD_BINDINGS_SOURCEFILES} ${KEMFIELD_BINDINGS_HEADERFILES} +) +add_library (KEMFieldBindingsHeaders INTERFACE) - if (${PROJECT_NAME}_USE_VTK) - list (APPEND KEMFIELD_BINDINGS_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/FieldSolvers/Electric/include/KFMVTKElectrostaticTreeViewerBuilder.hh - ) - list (APPEND KEMFIELD_BINDINGS_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/FieldSolvers/Electric/src/KFMVTKElectrostaticTreeViewerBuilder.cc - ) - endif (${PROJECT_NAME}_USE_VTK) +# get header paths from collected header files +foreach(HEADER ${KEMFIELD_BINDINGS_HEADERFILES}) + get_filename_component(DIRNAME ${HEADER} DIRECTORY) + target_include_directories(KEMFieldBindings PUBLIC $) + target_include_directories(KEMFieldBindingsHeaders INTERFACE $) +endforeach(HEADER) +target_include_directories(KEMFieldBindings PUBLIC $) - add_library (KEMFieldBindings SHARED ${KEMFIELD_BINDINGS_SOURCEFILES} ${KEMFIELD_BINDINGS_HEADERFILES}) - target_link_libraries (KEMFieldBindings - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - KEMFieldElectricBoundaryIntegrators - KEMFieldsElectric - KEMFieldsMagnetic - KEMElectricFieldSolvers - KEMMagneticFieldSolvers - KEMMath - KEMVTKPart2 - KGeoBagInterface +target_link_libraries (KEMFieldBindings + PUBLIC + Kommon + KGeoBagBindings + KGeoBagInterface + KEMFieldElectricBoundaryIntegrators + KEMFieldsElectric + KEMFieldsMagnetic + KEMElectricFieldSolvers + KEMMagneticFieldSolvers + KEMVTKPart2 ) - kasper_install_headers (${KEMFIELD_BINDINGS_HEADERFILES}) - kasper_install_libraries (KEMFieldBindings) +kasper_install_headers (${KEMFIELD_BINDINGS_HEADERFILES}) +kasper_install_libraries (KEMFieldBindings KEMFieldBindingsHeaders) diff --git a/KEMField/Source/Bindings/Fields/Electric/include/KElectrostaticBoundaryFieldBuilder.hh b/KEMField/Source/Bindings/Fields/Electric/include/KElectrostaticBoundaryFieldBuilder.hh index 5a4962b55..12fc11063 100644 --- a/KEMField/Source/Bindings/Fields/Electric/include/KElectrostaticBoundaryFieldBuilder.hh +++ b/KEMField/Source/Bindings/Fields/Electric/include/KElectrostaticBoundaryFieldBuilder.hh @@ -12,6 +12,7 @@ #include "KEMBindingsMessage.hh" #include "KGElectrostaticBoundaryField.hh" #include "KSmartPointerRelease.hh" +#include "KIntegratingElectrostaticFieldSolver.hh" namespace katrin { @@ -142,20 +143,17 @@ template<> inline bool KElectrostaticBoundaryFieldBuilder::AddElement(KContainer template<> inline bool KElectrostaticBoundaryFieldBuilder::End() { - if (!fObject->GetChargeDensitySolver() && !fObject->GetFieldSolver()) { - BINDINGMSG(eError) << " No charge density solver and no field solver" - " set in field " - << GetName() << "!" << eom; - } - else if (!fObject->GetChargeDensitySolver()) { - BINDINGMSG(eError) << " No charge density solver" - " set in field " + if (!fObject->GetChargeDensitySolver()) { + BINDINGMSG(eError) << " No charge density solver set in field " << GetName() << "!" << eom; + return false; } else if (!fObject->GetFieldSolver()) { - BINDINGMSG(eError) << " No field solver" - " set in field " - << GetName() << "!" << eom; + BINDINGMSG(eWarning) << " No electric field solver set in field " + << GetName() << " - falling back to integrating solver!" << eom; + auto solver = new KEMField::KIntegratingElectrostaticFieldSolver(); + fObject->SetFieldSolver(solver); + return true; } else return true; diff --git a/KEMField/Source/Bindings/Fields/Electric/include/KVTKViewerVisitorBuilder.hh b/KEMField/Source/Bindings/Fields/Electric/include/KVTKViewerVisitorBuilder.hh index d15d9ec18..bff354bc0 100644 --- a/KEMField/Source/Bindings/Fields/Electric/include/KVTKViewerVisitorBuilder.hh +++ b/KEMField/Source/Bindings/Fields/Electric/include/KVTKViewerVisitorBuilder.hh @@ -23,8 +23,12 @@ template<> inline bool KVTKViewerVisitorBuilder::AddAttribute(KContainer* aConta std::string name = ""; aContainer->CopyTo(name); fObject->SetFile(name); - - + return true; + } + if (aContainer->GetName() == "path") { + std::string name = ""; + aContainer->CopyTo(name); + fObject->SetPath(name); return true; } if (aContainer->GetName() == "view") { diff --git a/KEMField/Source/Bindings/Fields/Electric/src/KVTKViewerVisitorBuilder.cc b/KEMField/Source/Bindings/Fields/Electric/src/KVTKViewerVisitorBuilder.cc index cbc1716ab..88e8bce44 100644 --- a/KEMField/Source/Bindings/Fields/Electric/src/KVTKViewerVisitorBuilder.cc +++ b/KEMField/Source/Bindings/Fields/Electric/src/KVTKViewerVisitorBuilder.cc @@ -18,8 +18,11 @@ namespace katrin template<> KVTKViewerVisitorBuilder::~KComplexElement() = default; STATICINT sKVTKViewerVisitorStructure = - KVTKViewerVisitorBuilder::Attribute("file") + KVTKViewerVisitorBuilder::Attribute("view") + - KVTKViewerVisitorBuilder::Attribute("save") + KVTKViewerVisitorBuilder::Attribute("preprocessing") + + KVTKViewerVisitorBuilder::Attribute("file") + + KVTKViewerVisitorBuilder::Attribute("path") + + KVTKViewerVisitorBuilder::Attribute("view") + + KVTKViewerVisitorBuilder::Attribute("save") + + KVTKViewerVisitorBuilder::Attribute("preprocessing") + KVTKViewerVisitorBuilder::Attribute("postprocessing"); STATICINT sKElectrostaticBoundaryField = diff --git a/KEMField/Source/Bindings/Fields/Magnetic/include/KStaticElectromagnetFieldBuilder.hh b/KEMField/Source/Bindings/Fields/Magnetic/include/KStaticElectromagnetFieldBuilder.hh index f4085bc6f..bb40ddc71 100644 --- a/KEMField/Source/Bindings/Fields/Magnetic/include/KStaticElectromagnetFieldBuilder.hh +++ b/KEMField/Source/Bindings/Fields/Magnetic/include/KStaticElectromagnetFieldBuilder.hh @@ -12,6 +12,7 @@ #include "KEMBindingsMessage.hh" #include "KGStaticElectromagnetField.hh" #include "KSmartPointerRelease.hh" +#include "KIntegratingMagnetostaticFieldSolver.hh" namespace katrin { @@ -115,10 +116,11 @@ template<> inline bool KStaticElectromagnetFieldBuilder::AddElement(KContainer* template<> inline bool KStaticElectromagnetFieldBuilder::End() { if (!(fObject->GetFieldSolver())) { - BINDINGMSG(eError) << " No magnetic field solver " - "set in field " - << GetName() << "!" << eom; - return false; + BINDINGMSG(eWarning) << " No magnetic field solver set in field " + << GetName() << " - falling back to integrating solver!" << eom; + auto solver = new KEMField::KIntegratingMagnetostaticFieldSolver(); + fObject->SetFieldSolver(solver); + return true; } else return true; diff --git a/KEMField/Source/BoundaryIntegrals/Core/CMakeLists.txt b/KEMField/Source/BoundaryIntegrals/Core/CMakeLists.txt index 079350a5d..10e575909 100644 --- a/KEMField/Source/BoundaryIntegrals/Core/CMakeLists.txt +++ b/KEMField/Source/BoundaryIntegrals/Core/CMakeLists.txt @@ -1,12 +1,16 @@ # CMakeLists for KEMField/BoundaryIntegrals # Author: T.J. Corona -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - -set (LINEARALGEBRA_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KBoundaryIntegralMatrix.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KBoundaryIntegralVector.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KBoundaryIntegralSolutionVector.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KBoundaryMatrixGenerator.hh +set (BOUNDARYINTEGRALS_HEADERFILES + ${CMAKE_CURRENT_SOURCE_DIR}/include/KBoundaryIntegralMatrix.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KBoundaryIntegralVector.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KBoundaryIntegralSolutionVector.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KBoundaryMatrixGenerator.hh ) +add_library(KEMBoundaryIntegralsCore INTERFACE) +target_include_directories(KEMBoundaryIntegralsCore + INTERFACE $ $) + +kasper_install_headers (${BOUNDARYINTEGRALS_HEADERFILES}) +kasper_install_libraries (KEMBoundaryIntegralsCore) diff --git a/KEMField/Source/BoundaryIntegrals/Core/include/KBoundaryIntegralMatrix.hh b/KEMField/Source/BoundaryIntegrals/Core/include/KBoundaryIntegralMatrix.hh index 39da0d532..11c95a62d 100644 --- a/KEMField/Source/BoundaryIntegrals/Core/include/KBoundaryIntegralMatrix.hh +++ b/KEMField/Source/BoundaryIntegrals/Core/include/KBoundaryIntegralMatrix.hh @@ -70,14 +70,20 @@ KBoundaryIntegralMatrix::KBoundaryIntegralMatrix(cons basisDim2 *= basisDim2; unsigned int num_elements = c.size() * c.size(); + unsigned int array_length = num_elements * basisDim2; + unsigned int mem_size = array_length * (sizeof(ValueType) + sizeof(bool)); if (num_elements > 16384) // this would use about 2 GiB of RAM { - kem_cout(eWarning) << "Resizing matrix cache to " << num_elements << " elements" << eom; + kem_cout(eWarning) << "Resizing matrix cache to " << num_elements << " elements will use ca. " << mem_size/(1024*1024) << " MiB of memory" << eom; } - fValueIsCached.resize(num_elements * basisDim2, false); - fCachedValue.resize(num_elements * basisDim2); + fValueIsCached.resize(array_length, false); + fCachedValue.resize(array_length); + + if (fValueIsCached.size() < array_length || fCachedValue.size() < array_length) { + kem_cout(eError) << "Failed to resize matrix cache to " << num_elements << eom; + } } } diff --git a/KEMField/Source/BoundaryIntegrals/Electrostatic/CMakeLists.txt b/KEMField/Source/BoundaryIntegrals/Electrostatic/CMakeLists.txt index 1d700906d..c1803c341 100644 --- a/KEMField/Source/BoundaryIntegrals/Electrostatic/CMakeLists.txt +++ b/KEMField/Source/BoundaryIntegrals/Electrostatic/CMakeLists.txt @@ -1,31 +1,25 @@ # CMakeLists for KEMField/BoundaryIntegrals/Electrostatic # Author: T.J. Corona -kasper_internal_include_directories(Core/include) -kasper_internal_include_directories(Analytic/include) -kasper_internal_include_directories(Numeric/include) -kasper_internal_include_directories(Reference/include) -kasper_internal_include_directories(RWG/include) - set (ELECTROSTATICBOUNDARYINTEGRALS_HEADERFILES Core/include/KElectrostaticElementIntegrator.hh Core/include/KElectrostaticBoundaryIntegrator.hh Core/include/KElectrostaticBoundaryIntegratorFactory.hh - + Analytic/include/KElectrostaticAnalyticTriangleIntegrator.hh Analytic/include/KElectrostaticAnalyticRectangleIntegrator.hh Analytic/include/KElectrostaticAnalyticRingIntegrator.hh Analytic/include/KElectrostaticAnalyticLineSegmentIntegrator.hh Analytic/include/KElectrostaticAnalyticConicSectionIntegrator.hh - + Numeric/include/KElectrostaticCubatureTriangleIntegrator.hh Numeric/include/KElectrostaticCubatureRectangleIntegrator.hh Numeric/include/KElectrostaticQuadratureLineSegmentIntegrator.hh - + Reference/include/KElectrostaticBiQuadratureTriangleIntegrator.hh Reference/include/KElectrostaticBiQuadratureRectangleIntegrator.hh Reference/include/KElectrostatic256NodeQuadratureLineSegmentIntegrator.hh - + RWG/include/KElectrostaticRWGTriangleIntegrator.hh RWG/include/KElectrostaticRWGRectangleIntegrator.hh ) @@ -33,35 +27,42 @@ set (ELECTROSTATICBOUNDARYINTEGRALS_HEADERFILES set (ELECTROSTATICBOUNDARYINTEGRALS_SOURCEFILES Core/src/KElectrostaticBoundaryIntegrator.cc Core/src/KElectrostaticBoundaryIntegratorFactory.cc - + Analytic/src/KElectrostaticAnalyticTriangleIntegrator.cc Analytic/src/KElectrostaticAnalyticRectangleIntegrator.cc Analytic/src/KElectrostaticAnalyticRingIntegrator.cc Analytic/src/KElectrostaticAnalyticLineSegmentIntegrator.cc Analytic/src/KElectrostaticAnalyticConicSectionIntegrator.cc - + Numeric/src/KElectrostaticCubatureTriangleIntegrator.cc Numeric/src/KElectrostaticCubatureRectangleIntegrator.cc Numeric/src/KElectrostaticQuadratureLineSegmentIntegrator.cc Reference/src/KElectrostaticBiQuadratureTriangleIntegrator.cc - Reference/src/KElectrostaticBiQuadratureRectangleIntegrator.cc + Reference/src/KElectrostaticBiQuadratureRectangleIntegrator.cc Reference/src/KElectrostatic256NodeQuadratureLineSegmentIntegrator.cc - + RWG/src/KElectrostaticRWGTriangleIntegrator.cc RWG/src/KElectrostaticRWGRectangleIntegrator.cc ) -################################################## +add_library (KEMElectrostaticBoundaryIntegrals SHARED + ${ELECTROSTATICBOUNDARYINTEGRALS_SOURCEFILES} ${ELECTROSTATICBOUNDARYINTEGRALS_HEADERFILES}) + +# get header paths from collected header files +foreach(HEADER ${ELECTROSTATICBOUNDARYINTEGRALS_HEADERFILES}) + get_filename_component(DIRNAME ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER} DIRECTORY) + target_include_directories(KEMElectrostaticBoundaryIntegrals PUBLIC $) +endforeach(HEADER) +target_include_directories(KEMElectrostaticBoundaryIntegrals PUBLIC $) -add_library (KEMElectrostaticBoundaryIntegrals SHARED ${ELECTROSTATICBOUNDARYINTEGRALS_SOURCEFILES} ${ELECTROSTATICBOUNDARYINTEGRALS_HEADERFILES}) target_link_libraries (KEMElectrostaticBoundaryIntegrals - KEMMath - KEMSurfaces - KEMCore - KEMFieldExceptions - ${GSL_LIBRARIES}) + PUBLIC + KEMCore + KEMSurfaces + KEMFieldExceptions + KEMBoundaryIntegralsCore +) kasper_install_headers (${ELECTROSTATICBOUNDARYINTEGRALS_HEADERFILES}) kasper_install_libraries (KEMElectrostaticBoundaryIntegrals) - diff --git a/KEMField/Source/BoundaryIntegrals/Magnetostatic/CMakeLists.txt b/KEMField/Source/BoundaryIntegrals/Magnetostatic/CMakeLists.txt index 17ee56aba..5c860a97d 100644 --- a/KEMField/Source/BoundaryIntegrals/Magnetostatic/CMakeLists.txt +++ b/KEMField/Source/BoundaryIntegrals/Magnetostatic/CMakeLists.txt @@ -1,26 +1,30 @@ # CMakeLists for KEMField/MagnetostaticBoundaryIntegrals # Author: T.J. Corona -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (MAGNETOSTATICBOUNDARYINTEGRALS_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KMagnetostaticBoundaryIntegrator.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KMagnetostaticRingIntegrator.hh + #${CMAKE_CURRENT_SOURCE_DIR}/include/KMagnetostaticRingIntegrator.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KMagnetostaticLineSegmentIntegrator.hh ) set (MAGNETOSTATICBOUNDARYINTEGRALS_SOURCEFILES ${CMAKE_CURRENT_SOURCE_DIR}/src/KMagnetostaticBoundaryIntegrator.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KMagnetostaticRingIntegrator.cc + #${CMAKE_CURRENT_SOURCE_DIR}/src/KMagnetostaticRingIntegrator.cc ${CMAKE_CURRENT_SOURCE_DIR}/src/KMagnetostaticLineSegmentIntegrator.cc - ) +) ################################################## -add_library (KEMMagnetostaticBoundaryIntegrals SHARED ${MAGNETOSTATICBOUNDARYINTEGRALS_SOURCEFILES} ${MAGNETOSTATICBOUNDARYINTEGRALS_HEADERFILES}) +add_library (KEMMagnetostaticBoundaryIntegrals SHARED + ${MAGNETOSTATICBOUNDARYINTEGRALS_SOURCEFILES} ${MAGNETOSTATICBOUNDARYINTEGRALS_HEADERFILES}) +target_include_directories(KEMMagnetostaticBoundaryIntegrals + PUBLIC $ $) target_link_libraries (KEMMagnetostaticBoundaryIntegrals -KEMMath KEMSurfaces KEMCore ${GSL_LIBRARIES}) + PUBLIC + KEMCore + KEMSurfaces + KEMBoundaryIntegralsCore +) kasper_install_headers (${MAGNETOSTATICBOUNDARYINTEGRALS_HEADERFILES}) kasper_install_libraries (KEMMagnetostaticBoundaryIntegrals) - diff --git a/KEMField/Source/BoundaryIntegrals/Magnetostatic/include/KMagnetostaticBoundaryIntegrator.hh b/KEMField/Source/BoundaryIntegrals/Magnetostatic/include/KMagnetostaticBoundaryIntegrator.hh index 25e00dcd0..9f10b9a6d 100644 --- a/KEMField/Source/BoundaryIntegrals/Magnetostatic/include/KMagnetostaticBoundaryIntegrator.hh +++ b/KEMField/Source/BoundaryIntegrals/Magnetostatic/include/KMagnetostaticBoundaryIntegrator.hh @@ -115,7 +115,7 @@ class KMagnetostaticBoundaryIntegrator : public KMagnetostaticLineSegmentIntegra ValueType fValue; }; -template void KMagnetostaticBoundaryIntegrator::ComputeBoundaryIntegral(SourceShape& source) +template void KMagnetostaticBoundaryIntegrator::ComputeBoundaryIntegral(SourceShape& /*source*/) { // if (fBoundaryVisitor.IsDirichlet()) // { diff --git a/KEMField/Source/BoundaryIntegrals/Magnetostatic/src/KMagnetostaticBoundaryIntegrator.cc b/KEMField/Source/BoundaryIntegrals/Magnetostatic/src/KMagnetostaticBoundaryIntegrator.cc index 72fab9612..f205923e7 100644 --- a/KEMField/Source/BoundaryIntegrals/Magnetostatic/src/KMagnetostaticBoundaryIntegrator.cc +++ b/KEMField/Source/BoundaryIntegrals/Magnetostatic/src/KMagnetostaticBoundaryIntegrator.cc @@ -39,13 +39,13 @@ KMagnetostaticBasis::ValueType KMagnetostaticBoundaryIntegrator::BoundaryValue(K { fBoundaryVisitor.SetBoundaryIndex(i); surface->Accept(fBoundaryVisitor); - return fBoundaryVisitor.GetBoundaryValue(i); + return fBoundaryVisitor.GetBoundaryValue(); } KMagnetostaticBasis::ValueType& KMagnetostaticBoundaryIntegrator::BasisValue(KSurfacePrimitive* surface, unsigned int i) { fBasisVisitor.SetBasisIndex(i); surface->Accept(fBasisVisitor); - return fBasisVisitor.GetBasisValue(i); + return fBasisVisitor.GetBasisValue(); } } // namespace KEMField diff --git a/KEMField/Source/BoundaryIntegrals/Magnetostatic/src/KMagnetostaticLineSegmentIntegrator.cc b/KEMField/Source/BoundaryIntegrals/Magnetostatic/src/KMagnetostaticLineSegmentIntegrator.cc index d60536a59..4480d3726 100644 --- a/KEMField/Source/BoundaryIntegrals/Magnetostatic/src/KMagnetostaticLineSegmentIntegrator.cc +++ b/KEMField/Source/BoundaryIntegrals/Magnetostatic/src/KMagnetostaticLineSegmentIntegrator.cc @@ -2,7 +2,7 @@ namespace KEMField { -KThreeVector KMagnetostaticLineSegmentIntegrator::VectorPotential(const KLineSegment* source, const KPosition& P) const +KFieldVector KMagnetostaticLineSegmentIntegrator::VectorPotential(const KLineSegment* source, const KPosition& P) const { double r0 = (source->GetP0() - P).Magnitude(); double r1 = (source->GetP1() - P).Magnitude(); @@ -15,7 +15,7 @@ KThreeVector KMagnetostaticLineSegmentIntegrator::VectorPotential(const KLineSeg } -KThreeVector KMagnetostaticLineSegmentIntegrator::MagneticField(const KLineSegment* source, const KPosition& P) const +KFieldVector KMagnetostaticLineSegmentIntegrator::MagneticField(const KLineSegment* source, const KPosition& P) const { KPosition r0 = P - source->GetP0(); KPosition r1 = P - source->GetP1(); @@ -32,19 +32,19 @@ KThreeVector KMagnetostaticLineSegmentIntegrator::MagneticField(const KLineSegme return r0.Cross(i).Unit() * prefac; } -KThreeVector KMagnetostaticLineSegmentIntegrator::VectorPotential(const KSymmetryGroup* source, +KFieldVector KMagnetostaticLineSegmentIntegrator::VectorPotential(const KSymmetryGroup* source, const KPosition& P) const { - KThreeVector A; + KFieldVector A; for (auto it : *source) A += VectorPotential(it, P); return A; } -KThreeVector KMagnetostaticLineSegmentIntegrator::MagneticField(const KSymmetryGroup* source, +KFieldVector KMagnetostaticLineSegmentIntegrator::MagneticField(const KSymmetryGroup* source, const KPosition& P) const { - KThreeVector magneticField(0., 0., 0.); + KFieldVector magneticField(0., 0., 0.); for (auto it : *source) magneticField += MagneticField(it, P); return magneticField; diff --git a/KEMField/Source/BoundaryIntegrals/Magnetostatic/src/KMagnetostaticRingIntegrator.cc b/KEMField/Source/BoundaryIntegrals/Magnetostatic/src/KMagnetostaticRingIntegrator.cc index 52a9cf801..fc4d2ea55 100644 --- a/KEMField/Source/BoundaryIntegrals/Magnetostatic/src/KMagnetostaticRingIntegrator.cc +++ b/KEMField/Source/BoundaryIntegrals/Magnetostatic/src/KMagnetostaticRingIntegrator.cc @@ -6,7 +6,7 @@ namespace KEMField { -KThreeVector KMagnetostaticRingIntegrator::VectorPotential(const KRing* source, const KPosition& P) const +KFieldVector KMagnetostaticRingIntegrator::VectorPotential(const KRing* source, const KPosition& P) const { static KCompleteEllipticIntegral1stKind K_elliptic; static KEllipticEMinusKOverkSquared EK_elliptic; @@ -31,10 +31,10 @@ KThreeVector KMagnetostaticRingIntegrator::VectorPotential(const KRing* source, sine = P[1] / r; } - return KThreeVector(-sine * A_theta, cosine * A_theta, 0.); + return KFieldVector(-sine * A_theta, cosine * A_theta, 0.); } -KThreeVector KMagnetostaticRingIntegrator::MagneticField(const KRing* source, const KPosition& P) const +KFieldVector KMagnetostaticRingIntegrator::MagneticField(const KRing* source, const KPosition& P) const { static KCompleteEllipticIntegral1stKind K_elliptic; static KCompleteEllipticIntegral2ndKind E_elliptic; @@ -70,21 +70,21 @@ KThreeVector KMagnetostaticRingIntegrator::MagneticField(const KRing* source, co sine = P[1] / r; } - return KThreeVector(cosine * B_r, sine * B_r, B_z); + return KFieldVector(cosine * B_r, sine * B_r, B_z); } -KThreeVector KMagnetostaticRingIntegrator::VectorPotential(const KSymmetryGroup* source, +KFieldVector KMagnetostaticRingIntegrator::VectorPotential(const KSymmetryGroup* source, const KPosition& P) const { - KThreeVector A; + KFieldVector A; for (KSymmetryGroup::ShapeCIt it = source->begin(); it != source->end(); ++it) A += VectorPotential(*it, P); return A; } -KThreeVector KMagnetostaticRingIntegrator::MagneticField(const KSymmetryGroup* source, const KPosition& P) const +KFieldVector KMagnetostaticRingIntegrator::MagneticField(const KSymmetryGroup* source, const KPosition& P) const { - KThreeVector magneticField(0., 0., 0.); + KFieldVector magneticField(0., 0., 0.); for (KSymmetryGroup::ShapeCIt it = source->begin(); it != source->end(); ++it) magneticField += MagneticField(*it, P); return magneticField; diff --git a/KEMField/Source/Core/CMakeLists.txt b/KEMField/Source/Core/CMakeLists.txt index 808e3cfad..4f274590c 100644 --- a/KEMField/Source/Core/CMakeLists.txt +++ b/KEMField/Source/Core/CMakeLists.txt @@ -3,111 +3,91 @@ # Bindings need to be linked against KGeoBag, Kommon and KMessage -#option (${PROJECT_NAME}_SILENT "Disable all messaging" OFF) -#if (${PROJECT_NAME}_SILENT) -# add_cflag (KEMFIELD_SILENT) -#endif (${PROJECT_NAME}_SILENT) - -kasper_find_module(Kommon) -add_cflag (KEMFIELD_USE_KOMMON) - -#cmake_dependent_option (${PROJECT_NAME}_USE_KMESSAGE "Use KMessage" ON "NOT ${PROJECT_NAME}_SILENT" OFF) - - -#if (${PROJECT_NAME}_USE_KMESSAGE) - add_cflag (KEMFIELD_USE_KMESSAGE) -#endif (${PROJECT_NAME}_USE_KMESSAGE) - -option (${PROJECT_NAME}_USE_MPI "Use MPI to accelerate calculations using multiple processors" OFF) -if (${PROJECT_NAME}_USE_MPI) - find_package(MPI) - if (MPI_CXX_FOUND) - if (MPI_COMPILER) # MPICH2 style - set (CMAKE_C_COMPILER ${MPI_COMPILER}) - set (CMAKE_CXX_COMPILER ${MPI_COMPILER}) - else (MPI_COMPILER) # OpenMPI style - set (CMAKE_C_COMPILER ${MPI_C_COMPILER}) - set (CMAKE_CXX_COMPILER ${MPI_CXX_COMPILER}) - endif (MPI_COMPILER) - else (MPI_CXX_FOUND) - message(WARNING "Warning: MPI not found on your system, using default compiler" ) - set (CMAKE_C_COMPILER mpicc) - set (CMAKE_CXX_COMPILER mpicxx) - endif (MPI_CXX_FOUND) - add_cflag (KEMFIELD_USE_MPI) - - set (CMAKE_C_COMPILER ${CMAKE_C_COMPILER} PARENT_SCOPE) - set (CMAKE_CXX_COMPILER ${CMAKE_CXX_COMPILER} PARENT_SCOPE) - set (CMAKE_STATIC_LIBRARY_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX} PARENT_SCOPE) - set (CMAKE_SHARED_LIBRARY_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX} PARENT_SCOPE) - set (CMAKE_EXECUTABLE_SUFFIX ${CMAKE_EXECUTABLE_SUFFIX} PARENT_SCOPE) -endif (${PROJECT_NAME}_USE_MPI) - -option(${PROJECT_NAME}_USE_REALTIME_CLOCK "Use real time clock for timing applications." OFF) -mark_as_advanced(FORCE ${PROJECT_NAME}_USE_REALTIME_CLOCK) -if (${PROJECT_NAME}_USE_REALTIME_CLOCK) - add_cflag (KEMFIELD_USE_REALTIME_CLOCK) -endif (${PROJECT_NAME}_USE_REALTIME_CLOCK) - -#set( ${PROJECT_NAME}_USE_ROOT OFF CACHE BOOL "(Required)" FORCE ) -set( ${PROJECT_NAME}_USE_ROOT ${KASPER_USE_ROOT} ) - -kasper_internal_include_directories (${CMAKE_CURRENT_SOURCE_DIR}/include) +option(KEMField_USE_REALTIME_CLOCK "Use real time clock for timing applications." OFF) +mark_as_advanced(FORCE KEMField_USE_REALTIME_CLOCK) set (KEMCORE_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KComplexStreamer.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KDataComparator.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KDataDisplay.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMCout.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMCoreMessage.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMConstants.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMStringUtils.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMTicker.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KFundamentalTypeCounter.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KFundamentalTypes.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KMPIEnvironment.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSmartPointer.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KTimer.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KTypelist.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KTypelistVisitor.hh - ) + ${CMAKE_CURRENT_SOURCE_DIR}/include/KComplexStreamer.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KDataComparator.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KDataDisplay.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMCout.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMCoreMessage.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMConstants.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMStringUtils.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMTicker.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KFundamentalTypeCounter.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KFundamentalTypes.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KMPIEnvironment.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSmartPointer.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KTimer.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KTypelist.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KTypelistVisitor.hh +) set (KEMCORE_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMConstants.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMCout.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMCoreMessage.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMStringUtils.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMTicker.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KFundamentalTypes.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KTimer.cc - ) - -if (${PROJECT_NAME}_USE_MPI) - list (APPEND KEMCORE_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KMPIInterface.hh + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMConstants.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMCout.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMCoreMessage.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMStringUtils.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMTicker.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KFundamentalTypes.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KTimer.cc +) + +if (KEMField_USE_MPI) + list (APPEND KEMCORE_HEADERFILES + ${CMAKE_CURRENT_SOURCE_DIR}/include/KMPIInterface.hh ) - list (APPEND KEMCORE_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/src/KMPIInterface.cc + list (APPEND KEMCORE_SOURCEFILES + ${CMAKE_CURRENT_SOURCE_DIR}/src/KMPIInterface.cc ) -endif (${PROJECT_NAME}_USE_MPI) +endif (KEMField_USE_MPI) -#if (${PROJECT_NAME}_USE_KMESSAGE) - list (APPEND KEMCORE_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KMessageInterface.hh +if (KEMField_USE_KMESSAGE) + list (APPEND KEMCORE_HEADERFILES + ${CMAKE_CURRENT_SOURCE_DIR}/include/KMessageInterface.hh ) - list (APPEND KEMCORE_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/src/KMessageInterface.cc + list (APPEND KEMCORE_SOURCEFILES + ${CMAKE_CURRENT_SOURCE_DIR}/src/KMessageInterface.cc ) -#endif (${PROJECT_NAME}_USE_KMESSAGE) +endif (KEMField_USE_KMESSAGE) -add_library (KEMCore SHARED ${KEMCORE_SOURCEFILES} ${KEMCORE_HEADERFILES}) -target_link_libraries (KEMCore ${Kommon_LIBRARIES}) +add_library (KEMCore SHARED + ${KEMCORE_SOURCEFILES} ${KEMCORE_HEADERFILES}) +target_include_directories(KEMCore + PUBLIC $ $) -add_executable( KSmartPointer_test test/KSmartPointer_test.cc ) - target_link_libraries( KSmartPointer_test KEMCore - ) +target_link_libraries (KEMCore + PUBLIC + Kommon +) - kasper_install_executables( KSmartPointer_test ) +target_compile_definitions( KEMCore PUBLIC KEMFIELD_USE_KOMMON ) + +if( KEMField_ENABLE_DEBUG ) + target_compile_definitions( KEMCore PUBLIC KEMField_ENABLE_DEBUG ) +endif( KEMField_ENABLE_DEBUG ) + +#if (KEMField_SILENT) +# target_compile_definitions(KEMCore PUBLIC KEMFIELD_SILENT) +#endif (KEMField_SILENT) + +if (KEMField_USE_KMESSAGE) + target_compile_definitions(KEMCore PUBLIC KEMFIELD_USE_KMESSAGE) +endif (KEMField_USE_KMESSAGE) + +if(KEMField_USE_MPI) + target_link_libraries(KEMCore PUBLIC MPI::MPI_CXX) + target_compile_definitions(KEMCore PUBLIC KEMFIELD_USE_MPI) +endif(KEMField_USE_MPI) + +if(KEMField_USE_REALTIME_CLOCK) + target_compile_definitions (KEMCore PUBLIC KEMFIELD_USE_REALTIME_CLOCK) +endif(KEMField_USE_REALTIME_CLOCK) kasper_install_headers (${KEMCORE_HEADERFILES}) kasper_install_libraries (KEMCore) + +# add_executable( KSmartPointer_test test/KSmartPointer_test.cc ) +# target_link_libraries( KSmartPointer_test KEMCore) +# kasper_install_executables( KSmartPointer_test ) diff --git a/KEMField/Source/Exceptions/CMakeLists.txt b/KEMField/Source/Exceptions/CMakeLists.txt index 1b2faaabe..724592e5a 100644 --- a/KEMField/Source/Exceptions/CMakeLists.txt +++ b/KEMField/Source/Exceptions/CMakeLists.txt @@ -1,36 +1,40 @@ # header files set( EXCEPTIONS_HEADER_BASENAMES - KKeyNotFoundException.hh - KEMSimpleException.hh + KKeyNotFoundException.hh + KEMSimpleException.hh ) set( EXCEPTIONS_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/include ) + foreach( BASENAME ${EXCEPTIONS_HEADER_BASENAMES} ) - list( APPEND EXCEPTIONS_HEADER_FILENAMES ${EXCEPTIONS_HEADER_PATH}/${BASENAME} ) + list( APPEND EXCEPTIONS_HEADER_FILENAMES ${EXCEPTIONS_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files set( EXCEPTIONS_SOURCE_BASENAMES - KKeyNotFoundException.cc - KEMSimpleException.cc + KKeyNotFoundException.cc + KEMSimpleException.cc ) set( EXCEPTIONS_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/src + ${CMAKE_CURRENT_SOURCE_DIR}/src ) foreach( BASENAME ${EXCEPTIONS_SOURCE_BASENAMES} ) - list( APPEND EXCEPTIONS_SOURCE_FILENAMES ${EXCEPTIONS_SOURCE_PATH}/${BASENAME} ) + list( APPEND EXCEPTIONS_SOURCE_FILENAMES ${EXCEPTIONS_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) # library -kasper_internal_include_directories( ${EXCEPTIONS_HEADER_PATH} ) -add_library( KEMFieldExceptions SHARED ${EXCEPTIONS_SOURCE_FILENAMES} ${EXCEPTIONS_HEADER_FILENAMES} ) -set_target_properties( KEMFieldExceptions PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) -#target_link_libraries( KEMFieldExceptions -# ${KEMField_LIBRARIES} -#) +add_library( KEMFieldExceptions SHARED + ${EXCEPTIONS_SOURCE_FILENAMES} ${EXCEPTIONS_HEADER_FILENAMES} ) +target_include_directories(KEMFieldExceptions + PUBLIC $ $) +target_link_libraries( KEMFieldExceptions + PUBLIC + Kommon +) +#set_target_properties( KEMFieldExceptions PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) # install kasper_install_headers( ${EXCEPTIONS_HEADER_FILENAMES} ) diff --git a/KEMField/Source/ExternalFields/Electromagnets/CMakeLists.txt b/KEMField/Source/ExternalFields/Electromagnets/CMakeLists.txt index eab83759c..626b5556a 100644 --- a/KEMField/Source/ExternalFields/Electromagnets/CMakeLists.txt +++ b/KEMField/Source/ExternalFields/Electromagnets/CMakeLists.txt @@ -1,47 +1,50 @@ # CMakeLists for KEMField/ExternalFields/Electromagnets # Author: T.J. Corona -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (ELECTROMAGNETS_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KCurrentLoop.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KCoil.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectromagnet.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSolenoid.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KLineCurrent.hh -# - ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectromagnetTypes.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectromagnetVisitor.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectromagnetContainer.hh -# - ${CMAKE_CURRENT_SOURCE_DIR}/include/KCurrentLoopIntegrator.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KCoilIntegrator.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSolenoidIntegrator.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KLineCurrentIntegrator.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectromagnetIntegrator.hh -# - ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectromagnetIntegratingFieldSolver.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KCurrentLoop.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KCoil.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectromagnet.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSolenoid.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KLineCurrent.hh + + ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectromagnetTypes.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectromagnetVisitor.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectromagnetContainer.hh + + ${CMAKE_CURRENT_SOURCE_DIR}/include/KCurrentLoopIntegrator.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KCoilIntegrator.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSolenoidIntegrator.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KLineCurrentIntegrator.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectromagnetIntegrator.hh + + ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectromagnetIntegratingFieldSolver.hh ) set (ELECTROMAGNETS_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/src/KCurrentLoop.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KCoil.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KSolenoid.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KLineCurrent.cc -# - ${CMAKE_CURRENT_SOURCE_DIR}/src/KCurrentLoopIntegrator.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KCoilIntegrator.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KSolenoidIntegrator.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KLineCurrentIntegrator.cc -# - ${CMAKE_CURRENT_SOURCE_DIR}/src/KElectromagnetIntegratingFieldSolver.cc - ) - -################################################## - -add_library (KEMElectromagnets SHARED ${ELECTROMAGNETS_SOURCEFILES} ${ELECTROMAGNETS_HEADERFILES}) -target_link_libraries (KEMElectromagnets KEMCore KEMMath ${GSL_LIBRARIES}) + ${CMAKE_CURRENT_SOURCE_DIR}/src/KCurrentLoop.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KCoil.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KSolenoid.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KLineCurrent.cc + + ${CMAKE_CURRENT_SOURCE_DIR}/src/KCurrentLoopIntegrator.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KCoilIntegrator.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KSolenoidIntegrator.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KLineCurrentIntegrator.cc + + ${CMAKE_CURRENT_SOURCE_DIR}/src/KElectromagnetIntegratingFieldSolver.cc +) + +add_library (KEMElectromagnets SHARED + ${ELECTROMAGNETS_SOURCEFILES} ${ELECTROMAGNETS_HEADERFILES}) +target_include_directories(KEMElectromagnets + PUBLIC $ $) +target_link_libraries (KEMElectromagnets + PUBLIC + KEMCore + KEMMath + KEMFieldSolverCore +) kasper_install_headers (${ELECTROMAGNETS_HEADERFILES}) kasper_install_libraries (KEMElectromagnets) - diff --git a/KEMField/Source/FastMultipole/Applications/AccuracyComparisonFastMultipole.cc b/KEMField/Source/FastMultipole/Applications/AccuracyComparisonFastMultipole.cc index 4d5bbdaff..b493bc2e2 100644 --- a/KEMField/Source/FastMultipole/Applications/AccuracyComparisonFastMultipole.cc +++ b/KEMField/Source/FastMultipole/Applications/AccuracyComparisonFastMultipole.cc @@ -57,6 +57,7 @@ using namespace KGeoBag; using namespace KEMField; +using namespace std; #ifdef KEMFIELD_USE_OPENCL KFMElectrostaticFastMultipoleFieldSolver_OpenCL* fast_solver; @@ -379,6 +380,8 @@ class SelectBoundaryElements : public KSelectiveVisitor::Visit; + void Visit(KTriangle& /*t*/) override { if (fAllowedElementMode == 0 || fAllowedElementMode == 1) { diff --git a/KEMField/Source/FastMultipole/Applications/CMakeLists.txt b/KEMField/Source/FastMultipole/Applications/CMakeLists.txt index 0b4870901..34cb2323e 100644 --- a/KEMField/Source/FastMultipole/Applications/CMakeLists.txt +++ b/KEMField/Source/FastMultipole/Applications/CMakeLists.txt @@ -1,92 +1,49 @@ # CMakeLists for FastMultipole/Test # Author: J. P. Barrett -option (${PROJECT_NAME}_ENABLE_FM_APP "Build fast multipole applications" OFF) -if (${PROJECT_NAME}_ENABLE_FM_APP) - enable_testing () -endif (${PROJECT_NAME}_ENABLE_FM_APP) +option (KEMField_ENABLE_FM_APP "Build Fast Multipole applications" OFF) -if (${PROJECT_NAME}_ENABLE_FM_APP) - - kasper_internal_include_directories(${${PROJECT_NAME}_INCLUDE_DIRS}) - - add_definitions( -Wno-overloaded-virtual ) +if (KEMField_ENABLE_FM_APP) set (FAST_MULTIPOLE_APP_LIBS - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - KFMCore - KFMMath - KFMMathUtilities - KVectorMath - KFMKernel - KFMElectrostatics - KFMInterfaceExtraction - KFMInterfaceFieldSolvers - KFMUtility - KEMCore - KEMFileManipulation - KEMHashGenerator - KEMStructuredASCII - KEMMath - KEMSurfaces - KEMIO - KEMElectrostaticBoundaryIntegrals - KGeoBagInterface + KEMFieldBindings ) - if (${PROJECT_NAME}_USE_VTK) - list (APPEND FAST_MULTIPOLE_APP_LIBS - KEMVTKPlugin - ) - endif (${PROJECT_NAME}_USE_VTK) - - if (${PROJECT_NAME}_USE_ROOT) - find_package(ROOT REQUIRED) - kasper_external_include_directories( ${ROOT_INCLUDE_DIRS} ) - list (APPEND FAST_MULTIPOLE_APP_LIBS - KEMRootPlugin - ) - endif (${PROJECT_NAME}_USE_ROOT) + if (KEMField_USE_VTK) + list (APPEND FAST_MULTIPOLE_APP_LIBS KEMVTKPlugin) + endif (KEMField_USE_VTK) - if (${PROJECT_NAME}_USE_OPENCL) - kasper_external_include_directories( ${OPENCL_INCLUDE_DIRS} ) - list (APPEND FAST_MULTIPOLE_APP_LIBS - KEMOpenCLPlugin - ) - endif (${PROJECT_NAME}_USE_OPENCL) + if (KEMField_USE_ROOT) + find_package(ROOT REQUIRED) + list (APPEND FAST_MULTIPOLE_APP_LIBS KEMRootPlugin) + endif (KEMField_USE_ROOT) - if (${PROJECT_NAME}_USE_PETSc) - list (APPEND FAST_MULTIPOLE_APP_LIBS - KEMPETScPlugin - ) - endif (${PROJECT_NAME}_USE_PETSc) + if (KEMField_USE_OPENCL) + list (APPEND FAST_MULTIPOLE_APP_LIBS KEMOpenCLPlugin) + endif (KEMField_USE_OPENCL) - if (${PROJECT_NAME}_USE_VTK) - list (APPEND FAST_MULTIPOLE_APP_LIBS - ${Kommon_Vtk_LIBRARIES} - ${VTK_LIBRARIES}) - endif (${PROJECT_NAME}_USE_VTK) + if (KEMField_USE_PETSc) + list (APPEND FAST_MULTIPOLE_APP_LIBS KEMPETScPlugin) + endif (KEMField_USE_PETSc) - set_property( - SOURCE + set_property(SOURCE #${CMAKE_CURRENT_SOURCE_DIR}/ComputeSphericalCapacitorFastMultipole.cc ${CMAKE_CURRENT_SOURCE_DIR}/AccuracyComparisonFastMultipole.cc ${CMAKE_CURRENT_SOURCE_DIR}/CompareChargeDensities.cc - APPEND PROPERTY COMPILE_DEFINITIONS DEFAULT_DATA_DIR="${DATA_INSTALL_DIR}/${${PROJECT_NAME}_DATA_DIR}" + APPEND PROPERTY COMPILE_DEFINITIONS DEFAULT_DATA_DIR="${DATA_INSTALL_DIR}/${KEMField_DATA_DIR}" ) add_executable (CompareChargeDensities - ${CMAKE_CURRENT_SOURCE_DIR}/CompareChargeDensities.cc) - target_link_libraries (CompareChargeDensities ${FAST_MULTIPOLE_APP_LIBS} ${KasperCommon_LIBRARIES}) + ${CMAKE_CURRENT_SOURCE_DIR}/CompareChargeDensities.cc) + target_link_libraries (CompareChargeDensities ${FAST_MULTIPOLE_APP_LIBS}) -# add_executable (ComputeSphericalCapacitorFastMultipole +# add_executable (ComputeSphericalCapacitorFastMultipole # ${CMAKE_CURRENT_SOURCE_DIR}/ComputeSphericalCapacitorFastMultipole.cc) -# target_link_libraries (ComputeSphericalCapacitorFastMultipole ${FAST_MULTIPOLE_APP_LIBS} ${KasperCommon_LIBRARIES}) +# target_link_libraries (ComputeSphericalCapacitorFastMultipole ${FAST_MULTIPOLE_APP_LIBS}) - add_executable (AccuracyComparisonFastMultipole + add_executable (AccuracyComparisonFastMultipole ${CMAKE_CURRENT_SOURCE_DIR}/AccuracyComparisonFastMultipole.cc) - target_link_libraries (AccuracyComparisonFastMultipole ${FAST_MULTIPOLE_APP_LIBS} ${KasperCommon_LIBRARIES}) + target_link_libraries (AccuracyComparisonFastMultipole ${FAST_MULTIPOLE_APP_LIBS}) kasper_install_executables ( CompareChargeDensities @@ -94,39 +51,37 @@ if (${PROJECT_NAME}_ENABLE_FM_APP) AccuracyComparisonFastMultipole ) - if (${PROJECT_NAME}_USE_ROOT) + if (KEMField_USE_ROOT) add_executable (ConvertFieldMapToROOT - ${CMAKE_CURRENT_SOURCE_DIR}/ConvertFieldMapToROOT.cc) - target_link_libraries (ConvertFieldMapToROOT ${FAST_MULTIPOLE_APP_LIBS} ${KasperCommon_LIBRARIES}) + ${CMAKE_CURRENT_SOURCE_DIR}/ConvertFieldMapToROOT.cc) + target_link_libraries (ConvertFieldMapToROOT ${FAST_MULTIPOLE_APP_LIBS}) kasper_install_executables ( ConvertFieldMapToROOT ) - endif (${PROJECT_NAME}_USE_ROOT) + endif (KEMField_USE_ROOT) - if (${PROJECT_NAME}_USE_VTK) + if (KEMField_USE_VTK) add_executable (ConvertFieldMapToVTK - ${CMAKE_CURRENT_SOURCE_DIR}/ConvertFieldMapToVTK.cc) - target_link_libraries (ConvertFieldMapToVTK ${FAST_MULTIPOLE_APP_LIBS} ${KasperCommon_LIBRARIES}) + ${CMAKE_CURRENT_SOURCE_DIR}/ConvertFieldMapToVTK.cc) + target_link_libraries (ConvertFieldMapToVTK ${FAST_MULTIPOLE_APP_LIBS}) add_executable (VisualizeElectrostaticMultipoleTree - ${CMAKE_CURRENT_SOURCE_DIR}/VisualizeElectrostaticMultipoleTree.cc) - target_link_libraries (VisualizeElectrostaticMultipoleTree ${FAST_MULTIPOLE_APP_LIBS} ${KasperCommon_LIBRARIES}) - + ${CMAKE_CURRENT_SOURCE_DIR}/VisualizeElectrostaticMultipoleTree.cc) + target_link_libraries (VisualizeElectrostaticMultipoleTree ${FAST_MULTIPOLE_APP_LIBS}) kasper_install_executables ( ConvertFieldMapToVTK VisualizeElectrostaticMultipoleTree ) - endif (${PROJECT_NAME}_USE_VTK) + endif (KEMField_USE_VTK) install (DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipoleApplicationFiles - DESTINATION ${${PROJECT_NAME}_CONFIG_INSTALL_DIR} - PATTERN "*.gitignore" EXCLUDE - ) - + DESTINATION ${KEMField_CONFIG_INSTALL_DIR} + PATTERN "*.gitignore" EXCLUDE + ) -endif (${PROJECT_NAME}_ENABLE_FM_APP) +endif (KEMField_ENABLE_FM_APP) diff --git a/KEMField/Source/FastMultipole/Applications/ConvertFieldMapToVTK.cc b/KEMField/Source/FastMultipole/Applications/ConvertFieldMapToVTK.cc index 8456dec63..cc4d45e5d 100644 --- a/KEMField/Source/FastMultipole/Applications/ConvertFieldMapToVTK.cc +++ b/KEMField/Source/FastMultipole/Applications/ConvertFieldMapToVTK.cc @@ -11,7 +11,6 @@ #include #include -#ifdef KEMFIELD_USE_VTK #include #include #include @@ -42,7 +41,6 @@ #include #include #include -#endif /* KEMFIELD_USE_VTK */ using namespace KEMField; diff --git a/KEMField/Source/FastMultipole/Applications/VisualizeElectrostaticMultipoleTree.cc b/KEMField/Source/FastMultipole/Applications/VisualizeElectrostaticMultipoleTree.cc index 7bea97b03..8a8660fb9 100644 --- a/KEMField/Source/FastMultipole/Applications/VisualizeElectrostaticMultipoleTree.cc +++ b/KEMField/Source/FastMultipole/Applications/VisualizeElectrostaticMultipoleTree.cc @@ -16,6 +16,7 @@ #include using namespace KEMField; +using namespace std; int main(int argc, char* argv[]) { diff --git a/KEMField/Source/FastMultipole/Core/CMakeLists.txt b/KEMField/Source/FastMultipole/Core/CMakeLists.txt index b6a000589..8297c7337 100644 --- a/KEMField/Source/FastMultipole/Core/CMakeLists.txt +++ b/KEMField/Source/FastMultipole/Core/CMakeLists.txt @@ -1,8 +1,6 @@ # CMakeLists for KEMField/FastMultipole/Core # Author: J. P. Barrett -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (KFMCORE_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMObjectHolder.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMObjectCollection.hh @@ -49,10 +47,15 @@ set (KFMCORE_SOURCEFILES ${CMAKE_CURRENT_SOURCE_DIR}/src/KFMElementLocalInfluenceRange.cc ) -################################################## - -add_library (KFMCore SHARED ${KFMCORE_SOURCEFILES} ${KFMCORE_HEADERFILES}) -target_link_libraries (KFMCore KEMCore) +add_library (KFMCore SHARED + ${KFMCORE_SOURCEFILES} ${KFMCORE_HEADERFILES}) +target_include_directories(KFMCore + PUBLIC $ $) +target_link_libraries (KFMCore + PUBLIC + KEMCore + KEMStructuredASCII +) kasper_install_headers (${KFMCORE_HEADERFILES}) kasper_install_libraries (KFMCore) diff --git a/KEMField/Source/FastMultipole/Electrostatics/CMakeLists.txt b/KEMField/Source/FastMultipole/Electrostatics/CMakeLists.txt index c27ae6853..638918983 100644 --- a/KEMField/Source/FastMultipole/Electrostatics/CMakeLists.txt +++ b/KEMField/Source/FastMultipole/Electrostatics/CMakeLists.txt @@ -1,8 +1,6 @@ # CMakeLists for KEMField/FastMultipole/Electrostatics # Author: J. P. Barrett -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (KFMELECTROSTATICS_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMElectrostaticElement.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMElectrostaticNode.hh @@ -27,7 +25,6 @@ set (KFMELECTROSTATICS_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMElectrostaticNodeWorkScoreCalculator.hh ) - set (KFMELECTROSTATICS_SOURCEFILES ${CMAKE_CURRENT_SOURCE_DIR}/src/KFMElectrostaticMultipoleSet.cc ${CMAKE_CURRENT_SOURCE_DIR}/src/KFMElectrostaticLocalCoefficientSet.cc @@ -44,19 +41,28 @@ set (KFMELECTROSTATICS_SOURCEFILES ${CMAKE_CURRENT_SOURCE_DIR}/src/KFMElectrostaticNodeWorkScoreCalculator.cc ) - if (${PROJECT_NAME}_USE_MPI) - list (APPEND KFMELECTROSTATICS_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMElectrostaticTreeBuilder_MPI.hh - ) - list (APPEND KFMELECTROSTATICS_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/src/KFMElectrostaticTreeBuilder_MPI.cc - ) - endif (${PROJECT_NAME}_USE_MPI) +if (KEMField_USE_MPI) + list (APPEND KFMELECTROSTATICS_HEADERFILES + ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMElectrostaticTreeBuilder_MPI.hh + ) + list (APPEND KFMELECTROSTATICS_SOURCEFILES + ${CMAKE_CURRENT_SOURCE_DIR}/src/KFMElectrostaticTreeBuilder_MPI.cc + ) +endif (KEMField_USE_MPI) -################################################## - -add_library (KFMElectrostatics SHARED ${KFMELECTROSTATICS_SOURCEFILES} ${KFMELECTROSTATICS_HEADERFILES}) -target_link_libraries (KFMElectrostatics KEMCore KFMCore KFMMath KFMMathUtilities KVectorMath KFMKernel KFMTree KEMFileManipulation) +add_library (KFMElectrostatics SHARED + ${KFMELECTROSTATICS_SOURCEFILES} ${KFMELECTROSTATICS_HEADERFILES}) +target_include_directories(KFMElectrostatics + PUBLIC $ $) +target_link_libraries (KFMElectrostatics + PUBLIC + KEMFileManipulation + KFMCore + KFMMath + KFMVectorMath + KFMKernel + KFMTree +) kasper_install_headers (${KFMELECTROSTATICS_HEADERFILES}) kasper_install_libraries (KFMElectrostatics) diff --git a/KEMField/Source/FastMultipole/Interface/BoundaryIntegrals/CMakeLists.txt b/KEMField/Source/FastMultipole/Interface/BoundaryIntegrals/CMakeLists.txt index c521db26e..baf99285b 100644 --- a/KEMField/Source/FastMultipole/Interface/BoundaryIntegrals/CMakeLists.txt +++ b/KEMField/Source/FastMultipole/Interface/BoundaryIntegrals/CMakeLists.txt @@ -1,8 +1,6 @@ # CMakeLists for KEMField/FastMultipole/Subdivision # Author: J. P. Barrett -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (INTERFACE_BOUNDARY_INTEGRAL_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMBoundaryIntegralMatrix.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMElectrostaticBoundaryIntegrator.hh @@ -11,12 +9,16 @@ set (INTERFACE_BOUNDARY_INTEGRAL_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMSparseBoundaryIntegralMatrix_CompressedRow.hh ) - if (${PROJECT_NAME}_USE_MPI) - list (APPEND INTERFACE_BOUNDARY_INTEGRAL_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMElectrostaticBoundaryIntegrator_MPI.hh - ) - endif (${PROJECT_NAME}_USE_MPI) +if (KEMField_USE_MPI) + list (APPEND INTERFACE_BOUNDARY_INTEGRAL_HEADERFILES + ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMElectrostaticBoundaryIntegrator_MPI.hh + ) +endif (KEMField_USE_MPI) -################################################## +add_library(KFMInterfaceBoundaryIntegral INTERFACE) +target_include_directories(KFMInterfaceBoundaryIntegral + INTERFACE $ $) +target_link_libraries(KFMInterfaceBoundaryIntegral INTERFACE KFMInterfaceFieldSolvers) kasper_install_headers (${INTERFACE_BOUNDARY_INTEGRAL_HEADERFILES}) +kasper_install_libraries (KFMInterfaceBoundaryIntegral) diff --git a/KEMField/Source/FastMultipole/Interface/Extraction/CMakeLists.txt b/KEMField/Source/FastMultipole/Interface/Extraction/CMakeLists.txt index dc3e072fe..b3cdafb14 100644 --- a/KEMField/Source/FastMultipole/Interface/Extraction/CMakeLists.txt +++ b/KEMField/Source/FastMultipole/Interface/Extraction/CMakeLists.txt @@ -1,8 +1,6 @@ # CMakeLists for KEMField/FastMultipole/Subdivision # Author: J. P. Barrett -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (INTERFACE_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMSurfaceToPointCloudConverter.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMElectrostaticBasisDataExtractor.hh @@ -21,10 +19,16 @@ set (INTERFACE_SOURCEFILES # ${CMAKE_CURRENT_SOURCE_DIR}/src/KFMElectrostaticElementContainerFlyweight.cc ) -################################################## - -add_library (KFMInterfaceExtraction SHARED ${INTERFACE_SOURCEFILES} ${INTERFACE_HEADERFILES}) -target_link_libraries (KFMInterfaceExtraction KEMMath KEMSurfaces KFMCore KFMElectrostatics) +add_library (KFMInterfaceExtraction SHARED + ${INTERFACE_SOURCEFILES} ${INTERFACE_HEADERFILES}) +target_include_directories(KFMInterfaceExtraction + PUBLIC $ $) +target_link_libraries (KFMInterfaceExtraction + PUBLIC + KEMSurfaces + KFMCore + KFMElectrostatics +) kasper_install_headers (${INTERFACE_HEADERFILES}) kasper_install_libraries (KFMInterfaceExtraction) diff --git a/KEMField/Source/FastMultipole/Interface/FieldSolvers/CMakeLists.txt b/KEMField/Source/FastMultipole/Interface/FieldSolvers/CMakeLists.txt index 6bf9b128a..faa288e25 100644 --- a/KEMField/Source/FastMultipole/Interface/FieldSolvers/CMakeLists.txt +++ b/KEMField/Source/FastMultipole/Interface/FieldSolvers/CMakeLists.txt @@ -1,8 +1,6 @@ # CMakeLists for KEMField/FastMultipole/Subdivision # Author: J. P. Barrett -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (INTERFACE_FIELDSOLVER_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMElectrostaticFastMultipoleFieldSolver.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMElectrostaticTreeConstructor.hh @@ -12,10 +10,16 @@ set (INTERFACE_FIELDSOLVER_SOURCEFILES ${CMAKE_CURRENT_SOURCE_DIR}/src/KFMElectrostaticFastMultipoleFieldSolver.cc ) -################################################## - -add_library (KFMInterfaceFieldSolvers SHARED ${INTERFACE_FIELDSOLVER_SOURCEFILES} ${INTERFACE_FIELDSOLVER_HEADERFILES}) -target_link_libraries (KFMInterfaceFieldSolvers KFMInterfaceExtraction KEMMath KEMSurfaces KFMCore KFMElectrostatics KEMElectrostaticBoundaryIntegrals KEMFieldExceptions ${GSL_LIBRARIES}) +add_library (KFMInterfaceFieldSolvers SHARED + ${INTERFACE_FIELDSOLVER_SOURCEFILES} ${INTERFACE_FIELDSOLVER_HEADERFILES}) +target_include_directories(KFMInterfaceFieldSolvers + PUBLIC $ $) +target_link_libraries (KFMInterfaceFieldSolvers + PUBLIC + KEMIntegratingSolver + KEMElectrostaticBoundaryIntegrals + KFMInterfaceExtraction +) kasper_install_headers (${INTERFACE_FIELDSOLVER_HEADERFILES}) kasper_install_libraries (KFMInterfaceFieldSolvers) diff --git a/KEMField/Source/FastMultipole/Kernel/CMakeLists.txt b/KEMField/Source/FastMultipole/Kernel/CMakeLists.txt index 398ea3f1f..8b14d22dd 100644 --- a/KEMField/Source/FastMultipole/Kernel/CMakeLists.txt +++ b/KEMField/Source/FastMultipole/Kernel/CMakeLists.txt @@ -1,8 +1,6 @@ # CMakeLists for KEMField/FastMultipole/Kernel # Author: J. P. Barrett -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (KERNEL_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMKernelExpansion.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMScalarMultipoleExpansion.hh @@ -23,10 +21,14 @@ set (KERNEL_SOURCEFILES ${CMAKE_CURRENT_SOURCE_DIR}/src/KFMScalarMultipoleExpansion.cc ) -################################################## - -add_library (KFMKernel SHARED ${KERNEL_SOURCEFILES} ${KERNEL_HEADERFILES}) -target_link_libraries (KFMKernel KFMCore KFMMath) +add_library (KFMKernel SHARED + ${KERNEL_SOURCEFILES} ${KERNEL_HEADERFILES}) +target_include_directories(KFMKernel + PUBLIC $ $) +target_link_libraries (KFMKernel + PUBLIC + KFMMath +) kasper_install_headers (${KERNEL_HEADERFILES}) kasper_install_libraries (KFMKernel) diff --git a/KEMField/Source/FastMultipole/Math/CMakeLists.txt b/KEMField/Source/FastMultipole/Math/CMakeLists.txt index 0ff3b7028..ccd84943e 100644 --- a/KEMField/Source/FastMultipole/Math/CMakeLists.txt +++ b/KEMField/Source/FastMultipole/Math/CMakeLists.txt @@ -1,8 +1,6 @@ # CMakeLists for KEMField/FastMultipole/Math # Author: J. P. Barrett -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (MATH_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMRealSphericalHarmonicExpansionRotator.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMComplexSphericalHarmonicExpansionRotator.hh @@ -33,8 +31,17 @@ set (MATH_SOURCEFILES ${CMAKE_CURRENT_SOURCE_DIR}/src/KFMDenseBlockSparseMatrixStructure.cc ) -add_library (KFMMath SHARED ${MATH_SOURCEFILES} ${MATH_HEADERFILES}) - target_link_libraries (KFMMath KFMCore KFMMathUtilities) +add_library (KFMMath SHARED + ${MATH_SOURCEFILES} ${MATH_HEADERFILES}) +target_include_directories(KFMMath + PUBLIC $ $) +target_link_libraries (KFMMath + PUBLIC + KEMMath + KEMLinearAlgebraCore + KFMCore + KFMMathUtilities +) kasper_install_headers (${MATH_HEADERFILES}) kasper_install_libraries (KFMMath) diff --git a/KEMField/Source/FastMultipole/Test/CMakeLists.txt b/KEMField/Source/FastMultipole/Test/CMakeLists.txt index c9ee55aa8..3a58736e2 100644 --- a/KEMField/Source/FastMultipole/Test/CMakeLists.txt +++ b/KEMField/Source/FastMultipole/Test/CMakeLists.txt @@ -1,74 +1,36 @@ # CMakeLists for FastMultipole/Test # Author: J. P. Barrett -option (${PROJECT_NAME}_ENABLE_FM_TEST "Build fast multipole developer test applications" OFF) +option (${PROJECT_NAME}_ENABLE_FM_TEST "Build Fast Multipole developer test applications" OFF) if (${PROJECT_NAME}_ENABLE_FM_TEST) - enable_testing () + enable_testing () endif (${PROJECT_NAME}_ENABLE_FM_TEST) if (${PROJECT_NAME}_ENABLE_FM_TEST) - kasper_internal_include_directories(${${PROJECT_NAME}_INCLUDE_DIRS}) - set (FAST_MULTIPOLE_TEST_LIBS - ${KOMMON_LIBRARIES} - ${KGeoBag_LIBRARIES} KGeoBagInterface + KEMLinearAlgebraPreconditioner KFMCore - KFMMath - KFMMathUtilities - KVectorMath - KFMKernel - KFMElectrostatics - KFMInterfaceExtraction - KFMInterfaceFieldSolvers - KFMUtility - KEMCore - KEMFileManipulation - KEMHashGenerator - KEMStructuredASCII - KEMMath - KEMSurfaces - KEMIO - KEMElectrostaticBoundaryIntegrals ) if (${PROJECT_NAME}_USE_VTK) - list (APPEND FAST_MULTIPOLE_TEST_LIBS - KEMVTKPlugin - ) + list (APPEND FAST_MULTIPOLE_TEST_LIBS KEMVTKPlugin) endif (${PROJECT_NAME}_USE_VTK) - if (${PROJECT_NAME}_USE_ROOT) - find_package(ROOT REQUIRED) - kasper_external_include_directories( ${ROOT_INCLUDE_DIRS} ) - list (APPEND FAST_MULTIPOLE_TEST_LIBS - KEMRootPlugin - ) + find_package(ROOT REQUIRED) + list (APPEND FAST_MULTIPOLE_TEST_LIBS KEMRootPlugin) endif (${PROJECT_NAME}_USE_ROOT) if (${PROJECT_NAME}_USE_OPENCL) - kasper_external_include_directories( ${OPENCL_INCLUDE_DIRS} ) - list (APPEND FAST_MULTIPOLE_TEST_LIBS - KEMOpenCLPlugin - ) + list (APPEND FAST_MULTIPOLE_TEST_LIBS KEMOpenCLPlugin) endif (${PROJECT_NAME}_USE_OPENCL) if (${PROJECT_NAME}_USE_PETSc) - list (APPEND FAST_MULTIPOLE_TEST_LIBS - KEMPETScPlugin - ) + list (APPEND FAST_MULTIPOLE_TEST_LIBS KEMPETScPlugin) endif (${PROJECT_NAME}_USE_PETSc) - if (${PROJECT_NAME}_USE_VTK) - list (APPEND FAST_MULTIPOLE_TEST_LIBS - ${Kommon_Vtk_LIBRARIES} - ${VTK_LIBRARIES}) - endif (${PROJECT_NAME}_USE_VTK) - - list(APPEND PROPERTY COMPILE_DEFINITIONS DEFAULT_DATA_DIR="${DATA_INSTALL_DIR}/${${PROJECT_NAME}_DATA_DIR}") - set(SOURCE_BASENAMES TestArrayMath TestBasicMatrixOperations @@ -101,14 +63,17 @@ if (${PROJECT_NAME}_ENABLE_FM_TEST) ) if (${PROJECT_NAME}_USE_OPENCL) - list(APPEND SOURCE_BASENAMES - TestMultidimensionalFastFourierTransformOpenCL - TestMultidimensionalFastFourierTransformSpeed - ) + list(APPEND SOURCE_BASENAMES + TestMultidimensionalFastFourierTransformOpenCL + TestMultidimensionalFastFourierTransformSpeed + ) endif (${PROJECT_NAME}_USE_OPENCL) foreach( BASENAME ${SOURCE_BASENAMES} ) add_executable( ${BASENAME} ${BASENAME}.cc ) + set_property(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/${BASENAME}.cc + APPEND PROPERTY COMPILE_DEFINITIONS DEFAULT_DATA_DIR="${DATA_INSTALL_DIR}/${KEMField_DATA_DIR}" + ) target_link_libraries( ${BASENAME} ${FAST_MULTIPOLE_TEST_LIBS} ) endforeach( BASENAME ) diff --git a/KEMField/Source/FastMultipole/Tree/CMakeLists.txt b/KEMField/Source/FastMultipole/Tree/CMakeLists.txt index f1cbf7e34..3c72922f3 100644 --- a/KEMField/Source/FastMultipole/Tree/CMakeLists.txt +++ b/KEMField/Source/FastMultipole/Tree/CMakeLists.txt @@ -1,12 +1,6 @@ # CMakeLists for KEMField/FastMultipole/Tree # Author: J. P. Barrett -set(KEMField_MULTIPOLE_BUFFER "32" CACHE STRING "Buffer size (MB) used for batched calculation of multipole moments.") -mark_as_advanced(FORCE KEMField_MULTIPOLE_BUFFER) -add_cflag(KEMFIELD_MULTIPOLE_BUFFER_SIZE_MB=${KEMField_MULTIPOLE_BUFFER}) - -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (TREE_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMSubdivisionStrategy.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMCubicSpaceTree.hh @@ -49,22 +43,31 @@ set (TREE_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMWorkLoadBalanceWeights.hh ) -if (${PROJECT_NAME}_USE_MPI) - list (APPEND TREE_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMCubicSpaceTreeStaticLoadBalancer.hh +if (KEMField_USE_MPI) + list (APPEND TREE_HEADERFILES + ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMCubicSpaceTreeStaticLoadBalancer.hh ) -endif (${PROJECT_NAME}_USE_MPI) - +endif (KEMField_USE_MPI) set (TREE_SOURCEFILES ${CMAKE_CURRENT_SOURCE_DIR}/src/KFMSubdivisionStrategy.cc ${CMAKE_CURRENT_SOURCE_DIR}/src/KFMElementMomentBatchCalculator.cc ) -################################################## +set(KEMField_MULTIPOLE_BUFFER "32" CACHE STRING "Buffer size (MB) used for batched calculation of multipole moments.") +mark_as_advanced(FORCE KEMField_MULTIPOLE_BUFFER) -add_library (KFMTree SHARED ${TREE_SOURCEFILES} ${TREE_HEADERFILES}) -target_link_libraries (KFMTree KFMCore KFMMath KFMMathUtilities KFMKernel KEMStructuredASCII) +add_library (KFMTree SHARED + ${TREE_SOURCEFILES} ${TREE_HEADERFILES}) +target_include_directories(KFMTree + PUBLIC $ $) + +target_compile_definitions(KFMTree PUBLIC KEMFIELD_MULTIPOLE_BUFFER_SIZE_MB=${KEMField_MULTIPOLE_BUFFER}) +target_link_libraries (KFMTree + PUBLIC + KFMCore + KFMMath +) kasper_install_headers (${TREE_HEADERFILES}) kasper_install_libraries (KFMTree) diff --git a/KEMField/Source/FastMultipole/Utility/CMakeLists.txt b/KEMField/Source/FastMultipole/Utility/CMakeLists.txt index 251b218ad..0d4a01830 100644 --- a/KEMField/Source/FastMultipole/Utility/CMakeLists.txt +++ b/KEMField/Source/FastMultipole/Utility/CMakeLists.txt @@ -1,8 +1,6 @@ # CMakeLists for FastMultipole/Utility # Author: J. P. Barrett -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (KFM_UTIL_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KFastMultipoleMatrixGenerator.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMElectrostaticTypes.hh @@ -21,39 +19,27 @@ set (KFM_UTIL_SOURCEFILES ${CMAKE_CURRENT_SOURCE_DIR}/src/KFMElectrostaticFastMultipoleBoundaryValueSolverConfiguration.cc ) -set (KFM_UTIL_LIBS +add_library (KFMUtility SHARED + ${KFM_UTIL_SOURCEFILES} ${KFM_UTIL_HEADERFILES}) +target_include_directories(KFMUtility + PUBLIC $ $) + +target_link_libraries (KFMUtility + PUBLIC + KEMLinearAlgebraPreconditioner + KEMLinearAlgebraSolvers KFMCore - KFMMath - KFMMathUtilities - KVectorMath - KFMKernel - KFMTree + KFMInterfaceBoundaryIntegral KFMElectrostatics - KFMInterfaceExtraction - KFMInterfaceFieldSolvers - KEMCore - KEMFieldExceptions - KEMFileManipulation - KEMHashGenerator - KEMLinearAlgebraSolvers - KEMStructuredASCII - KEMMath - KEMSurfaces - KEMIO ) -if(${PROJECT_NAME}_USE_OPENCL) - list (APPEND KFM_UTIL_LIBS KEMOpenCLPlugin ${OPENCL_LIBRARIES}) - add_cflag (KEMFIELD_USE_OPENCL) -endif(${PROJECT_NAME}_USE_OPENCL) - -if (${PROJECT_NAME}_USE_VTK) - list (APPEND KFM_UTIL_LIBS KEMVTKPlugin) - add_cflag (KEMFIELD_USE_VTK) -endif (${PROJECT_NAME}_USE_VTK) +if(KEMField_USE_OPENCL) + target_link_libraries(KFMUtility PUBLIC KEMOpenCLPlugin) +endif(KEMField_USE_OPENCL) -add_library (KFMUtility SHARED ${KFM_UTIL_SOURCEFILES} ${KFM_UTIL_HEADERFILES}) -target_link_libraries (KFMUtility ${Kommon_LIBRARIES} ${KGeoBag_LIBRARIES} ${KFM_UTIL_LIBS}) +if(KEMField_USE_VTK) + target_link_libraries(KFMUtility PUBLIC KEMVTKPlugin) +endif(KEMField_USE_VTK) kasper_install_headers (${KFM_UTIL_HEADERFILES}) kasper_install_libraries (KFMUtility) diff --git a/KEMField/Source/FieldSolvers/Core/CMakeLists.txt b/KEMField/Source/FieldSolvers/Core/CMakeLists.txt index 596531629..1a49bf4f0 100644 --- a/KEMField/Source/FieldSolvers/Core/CMakeLists.txt +++ b/KEMField/Source/FieldSolvers/Core/CMakeLists.txt @@ -1,11 +1,13 @@ # CMakeLists for KEMField/FieldSolvers/Core # Author: T.J. Corona -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (FIELDSOLVERSCORE_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KIntegratingFieldSolverTemplate.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KIntegratingFieldSolverTemplate.hh ) -kasper_install_headers (${FIELDSOLVERSCORE_HEADERFILES}) +add_library(KEMFieldSolverCore INTERFACE) +target_include_directories(KEMFieldSolverCore + INTERFACE $ $) +kasper_install_headers (${FIELDSOLVERSCORE_HEADERFILES}) +kasper_install_libraries (KEMFieldSolverCore) diff --git a/KEMField/Source/FieldSolvers/Integrating/CMakeLists.txt b/KEMField/Source/FieldSolvers/Integrating/CMakeLists.txt index a5c3776c3..a7e4ccdde 100644 --- a/KEMField/Source/FieldSolvers/Integrating/CMakeLists.txt +++ b/KEMField/Source/FieldSolvers/Integrating/CMakeLists.txt @@ -1,10 +1,14 @@ # CMakeLists for KEMField/FieldSolvers/Integrating # Author: Daniel Hilk -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (INTEGRATINGFIELDSOLVER_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectrostaticIntegratingFieldSolver.hh - ) + ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectrostaticIntegratingFieldSolver.hh +) + +add_library(KEMIntegratingSolver INTERFACE) +target_include_directories(KEMIntegratingSolver + INTERFACE $ $) +target_link_libraries(KEMIntegratingSolver INTERFACE KEMFieldSolverCore) kasper_install_headers (${INTEGRATINGFIELDSOLVER_HEADERFILES}) +kasper_install_libraries (KEMIntegratingSolver) diff --git a/KEMField/Source/FieldSolvers/ZonalHarmonic/Generator/CMakeLists.txt b/KEMField/Source/FieldSolvers/ZonalHarmonic/Generator/CMakeLists.txt index eed7bb925..f95ce541d 100644 --- a/KEMField/Source/FieldSolvers/ZonalHarmonic/Generator/CMakeLists.txt +++ b/KEMField/Source/FieldSolvers/ZonalHarmonic/Generator/CMakeLists.txt @@ -1,40 +1,44 @@ # CMakeLists for KEMField/FieldSolvers/ZonalHarmonic/Generator # Author: T.J. Corona -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (ZONALHARMONICGENERATOR_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KZonalHarmonicTypes.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KZHCoefficientGeneratorElement.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KZHCoefficientGeneratorCurrentLoop.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KZHCoefficientGeneratorSolenoid.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KZHCoefficientGeneratorCoil.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KZHCoefficientGeneratorRing.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KZHCoefficientGeneratorConicSection.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KZonalHarmonicTypes.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KZonalHarmonicCoefficientGenerator.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KZonalHarmonicSourcePoint.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KZonalHarmonicContainer.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KZonalHarmonicParameters.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KZHLegendreCoefficients.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KZonalHarmonicTypes.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KZHCoefficientGeneratorElement.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KZHCoefficientGeneratorCurrentLoop.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KZHCoefficientGeneratorSolenoid.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KZHCoefficientGeneratorCoil.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KZHCoefficientGeneratorRing.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KZHCoefficientGeneratorConicSection.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KZonalHarmonicTypes.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KZonalHarmonicCoefficientGenerator.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KZonalHarmonicSourcePoint.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KZonalHarmonicContainer.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KZonalHarmonicParameters.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KZHLegendreCoefficients.hh ) set (ZONALHARMONICGENERATOR_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/src/KZHCoefficientGeneratorElement.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KZHCoefficientGeneratorCurrentLoop.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KZHCoefficientGeneratorSolenoid.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KZHCoefficientGeneratorCoil.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KZHCoefficientGeneratorRing.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KZHCoefficientGeneratorConicSection.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KZonalHarmonicSourcePoint.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KZHLegendreCoefficients.cc - ) - -################################################## + ${CMAKE_CURRENT_SOURCE_DIR}/src/KZHCoefficientGeneratorElement.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KZHCoefficientGeneratorCurrentLoop.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KZHCoefficientGeneratorSolenoid.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KZHCoefficientGeneratorCoil.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KZHCoefficientGeneratorRing.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KZHCoefficientGeneratorConicSection.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KZonalHarmonicSourcePoint.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KZHLegendreCoefficients.cc +) -add_library (KEMZHGenerator SHARED ${ZONALHARMONICGENERATOR_SOURCEFILES} ${ZONALHARMONICGENERATOR_HEADERFILES}) -target_link_libraries (KEMZHGenerator KEMCore KEMSurfaces KEMElectromagnets) +add_library (KEMZHGenerator SHARED + ${ZONALHARMONICGENERATOR_SOURCEFILES} ${ZONALHARMONICGENERATOR_HEADERFILES}) +target_include_directories(KEMZHGenerator + PUBLIC $ $) +target_link_libraries (KEMZHGenerator + PUBLIC + KEMSurfaces + KEMElectromagnets + KEMElectrostaticBoundaryIntegrals + KEMHashGenerator +) kasper_install_headers (${ZONALHARMONICGENERATOR_HEADERFILES}) kasper_install_libraries (KEMZHGenerator) - diff --git a/KEMField/Source/FieldSolvers/ZonalHarmonic/Solver/CMakeLists.txt b/KEMField/Source/FieldSolvers/ZonalHarmonic/Solver/CMakeLists.txt index 15e551325..fc7332e78 100644 --- a/KEMField/Source/FieldSolvers/ZonalHarmonic/Solver/CMakeLists.txt +++ b/KEMField/Source/FieldSolvers/ZonalHarmonic/Solver/CMakeLists.txt @@ -1,27 +1,28 @@ # CMakeLists for KEMField/FieldSolvers/ZonalHarmonic/Solver # Author: T.J. Corona -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (ZONALHARMONICSOLVER_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KZonalHarmonicComputer.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KZonalHarmonicComputer.icc - ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectromagnetZonalHarmonicFieldSolver.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectrostaticZonalHarmonicFieldSolver.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KZonalHarmonicComputer.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KZonalHarmonicComputer.icc + ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectromagnetZonalHarmonicFieldSolver.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectrostaticZonalHarmonicFieldSolver.hh ) set (ZONALHARMONICSOLVER_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/src/KElectromagnetZonalHarmonicFieldSolver.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KElectrostaticZonalHarmonicFieldSolver.cc - ) - -################################################## + ${CMAKE_CURRENT_SOURCE_DIR}/src/KElectromagnetZonalHarmonicFieldSolver.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KElectrostaticZonalHarmonicFieldSolver.cc +) -add_library (KEMZHSolver SHARED ${ZONALHARMONICSOLVER_SOURCEFILES} ${ZONALHARMONICSOLVER_HEADERFILES}) -target_link_libraries (KEMZHSolver KEMCore KEMSurfaces -KEMElectromagnets KEMZHGenerator KEMElectrostaticBoundaryIntegrals -KEMMath KEMSurfaces KEMCore KEMFieldExceptions ${GSL_LIBRARIES}) +add_library (KEMZHSolver SHARED + ${ZONALHARMONICSOLVER_SOURCEFILES} ${ZONALHARMONICSOLVER_HEADERFILES}) +target_include_directories(KEMZHSolver + PUBLIC $ $) +target_link_libraries (KEMZHSolver + PUBLIC + KEMSurfaces + KEMIntegratingSolver + KEMZHGenerator +) kasper_install_headers (${ZONALHARMONICSOLVER_HEADERFILES}) kasper_install_libraries (KEMZHSolver) - diff --git a/KEMField/Source/FieldSolvers/ZonalHarmonic/Solver/src/KElectrostaticZonalHarmonicFieldSolver.cc b/KEMField/Source/FieldSolvers/ZonalHarmonic/Solver/src/KElectrostaticZonalHarmonicFieldSolver.cc index c7faea10d..eb57350b6 100644 --- a/KEMField/Source/FieldSolvers/ZonalHarmonic/Solver/src/KElectrostaticZonalHarmonicFieldSolver.cc +++ b/KEMField/Source/FieldSolvers/ZonalHarmonic/Solver/src/KElectrostaticZonalHarmonicFieldSolver.cc @@ -1,5 +1,7 @@ #include "KElectrostaticZonalHarmonicFieldSolver.hh" +#include "KEMCoreMessage.hh" + #include // #include "KShanksTransformation.hh" @@ -50,6 +52,7 @@ double KZonalHarmonicFieldSolver::Potential(const KPosition return std::accumulate(fSubsetFieldSolvers.begin(), fSubsetFieldSolvers.end(), phi, accumulator); } + kem_cout_debug("ZH solver falling back to direct integration at point <" << P.Z() << " " << P.Perp() << ">" << eom); return fIntegratingFieldSolver.Potential(P); } @@ -71,6 +74,7 @@ KFieldVector KZonalHarmonicFieldSolver::ElectricField(const return std::accumulate(fSubsetFieldSolvers.begin(), fSubsetFieldSolvers.end(), E, accumulator); } + kem_cout_debug("ZH solver falling back to direct integration at point <" << P.Z() << " " << P.Perp() << ">" << eom); return fIntegratingFieldSolver.ElectricField(P); } @@ -97,6 +101,7 @@ KZonalHarmonicFieldSolver::ElectricFieldAndPotential(const accumulator); } + kem_cout_debug("ZH solver falling back to direct integration at point <" << P.Z() << " " << P.Perp() << ">" << eom); return std::make_pair(fIntegratingFieldSolver.ElectricField(P), fIntegratingFieldSolver.Potential(P)); } diff --git a/KEMField/Source/IO/FileManipulation/CMakeLists.txt b/KEMField/Source/IO/FileManipulation/CMakeLists.txt index 832d1771c..8b5b04863 100644 --- a/KEMField/Source/IO/FileManipulation/CMakeLists.txt +++ b/KEMField/Source/IO/FileManipulation/CMakeLists.txt @@ -3,37 +3,44 @@ set(KEMField_SPARSE_MATRIX_BUFFER "32" CACHE STRING "Buffer size (MB) used for sparse matrices too large to fit in RAM.") mark_as_advanced(FORCE KEMField_SPARSE_MATRIX_BUFFER) -add_cflag(KEMFIELD_SPARSE_MATRIX_BUFFER_SIZE_MB=${KEMField_SPARSE_MATRIX_BUFFER}) set(KEMField_CACHE_DIR "${${PROJECT_NAME}_CACHE_INSTALL_DIR}" CACHE STRING "KEMField caching directory.") mark_as_advanced(FORCE KEMField_CACHE_DIR) - -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (FILEMANIPULATION_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMFile.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMFileInterface.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMSparseMatrixFileInterface.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMChunkedFileInterface.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMKSAFileInterface.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMFile.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMFileInterface.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMSparseMatrixFileInterface.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMChunkedFileInterface.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMKSAFileInterface.hh ) set (FILEMANIPULATION_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMFile.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMFileInterface.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMKSAFileInterface.cc - ) + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMFile.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMFileInterface.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMKSAFileInterface.cc +) set_property( - SOURCE - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMFile.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMFileInterface.cc - APPEND PROPERTY COMPILE_DEFINITIONS DEFAULT_SAVED_FILE_DIR="${KEMField_CACHE_DIR}" + SOURCE + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMFile.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMFileInterface.cc + APPEND PROPERTY COMPILE_DEFINITIONS DEFAULT_SAVED_FILE_DIR="${KEMField_CACHE_DIR}" ) -add_library (KEMFileManipulation SHARED ${FILEMANIPULATION_SOURCEFILES} ${FILEMANIPULATION_HEADERFILES} ${FILEMANIPULATION_DICT_OUTFILE}) -target_link_libraries (KEMFileManipulation KEMIO KEMStructuredASCII KEMCore ${GSL_LIBRARIES} ${OPENCL_LIBRARIES}) +add_library (KEMFileManipulation SHARED + ${FILEMANIPULATION_SOURCEFILES} ${FILEMANIPULATION_HEADERFILES} + ${FILEMANIPULATION_DICT_OUTFILE}) +target_include_directories(KEMStructuredASCII + PUBLIC $ $) + +target_compile_definitions(KEMStructuredASCII + PUBLIC KEMFIELD_SPARSE_MATRIX_BUFFER_SIZE_MB=${KEMField_SPARSE_MATRIX_BUFFER}) +target_link_libraries (KEMFileManipulation + PUBLIC + KEMIO + KEMHashGenerator +) kasper_install_headers (${FILEMANIPULATION_HEADERFILES}) kasper_install_libraries (KEMFileManipulation) diff --git a/KEMField/Source/IO/HashGenerator/CMakeLists.txt b/KEMField/Source/IO/HashGenerator/CMakeLists.txt index 23fbb196f..3e76907d8 100644 --- a/KEMField/Source/IO/HashGenerator/CMakeLists.txt +++ b/KEMField/Source/IO/HashGenerator/CMakeLists.txt @@ -1,22 +1,23 @@ # CMakeLists for KEMField/IO/HashGenerator # Author: T.J. Corona -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (HASHGENERATOR_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KMD5HashGenerator.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/md5.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KMD5HashGenerator.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/md5.hh ) set (HASHGENERATOR_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/src/md5.cc - ) - -################################################## + ${CMAKE_CURRENT_SOURCE_DIR}/src/md5.cc +) -add_library (KEMHashGenerator SHARED ${HASHGENERATOR_SOURCEFILES} ${HASHGENERATOR_HEADERFILES}) -target_link_libraries (KEMHashGenerator KEMCore KEMMath KGeoBagMath) +add_library (KEMHashGenerator SHARED + ${HASHGENERATOR_SOURCEFILES} ${HASHGENERATOR_HEADERFILES}) +target_include_directories(KEMHashGenerator + PUBLIC $ $) +target_link_libraries (KEMHashGenerator + PUBLIC + KEMCore +) kasper_install_headers (${HASHGENERATOR_HEADERFILES}) kasper_install_libraries (KEMHashGenerator) - diff --git a/KEMField/Source/IO/Streamers/CMakeLists.txt b/KEMField/Source/IO/Streamers/CMakeLists.txt index 06cedfc1a..06b183e0f 100644 --- a/KEMField/Source/IO/Streamers/CMakeLists.txt +++ b/KEMField/Source/IO/Streamers/CMakeLists.txt @@ -1,30 +1,32 @@ # CMakeLists for KEMField/IO # Author: T.J. Corona -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (IO_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KBinaryDataStreamer.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KMetadataStreamer.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSABuffer.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSADataStreamer.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSerializer.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KStreamedSizeOf.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KTransitiveStreamer.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KBinaryDataStreamer.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KMetadataStreamer.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSABuffer.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSADataStreamer.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSerializer.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KStreamedSizeOf.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KTransitiveStreamer.hh ) set (IO_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/src/KBinaryDataStreamer.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KMetadataStreamer.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KSABuffer.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KSADataStreamer.cc - ) - -################################################## + ${CMAKE_CURRENT_SOURCE_DIR}/src/KBinaryDataStreamer.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KMetadataStreamer.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KSABuffer.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KSADataStreamer.cc +) -add_library (KEMIO SHARED ${IO_SOURCEFILES} ${IO_HEADERFILES} ${IO_DICT_OUTFILE}) -target_link_libraries (KEMIO KEMStructuredASCII KEMCore ${GSL_LIBRARIES} ${OPENCL_LIBRARIES}) +add_library (KEMIO SHARED + ${IO_SOURCEFILES} ${IO_HEADERFILES} ${IO_DICT_OUTFILE}) +target_include_directories(KEMIO + PUBLIC $ $) +target_link_libraries (KEMIO + PUBLIC + KEMCore + KEMStructuredASCII +) kasper_install_headers (${IO_HEADERFILES}) kasper_install_libraries (KEMIO) - diff --git a/KEMField/Source/IO/StructuredASCII/CMakeLists.txt b/KEMField/Source/IO/StructuredASCII/CMakeLists.txt index f07fbd896..46a72ad54 100644 --- a/KEMField/Source/IO/StructuredASCII/CMakeLists.txt +++ b/KEMField/Source/IO/StructuredASCII/CMakeLists.txt @@ -44,18 +44,14 @@ set (STRUCTUREDASCII_HEADERFILES find_package(ZLIB QUIET) option (KEMField_USE_ZLIB "Use ZLib compression" ${ZLIB_FOUND}) if (KEMField_USE_ZLIB) - find_package(ZLIB REQUIRED) - kasper_external_include_directories (${ZLIB_INCLUDE_DIRS}) - add_cflag(KEMFIELD_USE_ZLIB) + find_package(ZLIB REQUIRED) else (KEMField_USE_ZLIB) - set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/include/miniz.hh PROPERTIES COMPILE_FLAGS -Wno-strict-aliasing) - list (APPEND STRUCTUREDASCII_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/miniz.hh + set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/include/miniz.hh PROPERTIES COMPILE_FLAGS -Wno-strict-aliasing) + list (APPEND STRUCTUREDASCII_HEADERFILES + ${CMAKE_CURRENT_SOURCE_DIR}/include/miniz.hh ) endif (KEMField_USE_ZLIB) -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (STRUCTUREDASCII_SOURCEFILES ${CMAKE_CURRENT_SOURCE_DIR}/src/KSAFileReader.cc ${CMAKE_CURRENT_SOURCE_DIR}/src/KSAFileWriter.cc @@ -68,20 +64,23 @@ set (STRUCTUREDASCII_SOURCEFILES ) if (NOT KEMField_USE_ZLIB) -set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/include/miniz.c PROPERTIES COMPILE_FLAGS -Wno-strict-aliasing) -list (APPEND STRUCTUREDASCII_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/miniz.c + set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/include/miniz.c PROPERTIES COMPILE_FLAGS -Wno-strict-aliasing) + list (APPEND STRUCTUREDASCII_SOURCEFILES + ${CMAKE_CURRENT_SOURCE_DIR}/include/miniz.c ) endif (NOT KEMField_USE_ZLIB) -################################################## - -add_library (KEMStructuredASCII SHARED ${STRUCTUREDASCII_SOURCEFILES} ${STRUCTUREDASCII_HEADERFILES}) +add_library (KEMStructuredASCII SHARED + ${STRUCTUREDASCII_SOURCEFILES} ${STRUCTUREDASCII_HEADERFILES}) +target_include_directories(KEMStructuredASCII + PUBLIC $ $) if (KEMField_USE_ZLIB) -target_link_libraries (KEMStructuredASCII ${ZLIB_LIBRARIES}) + target_compile_definitions(KEMStructuredASCII PUBLIC KEMFIELD_USE_ZLIB ) + target_include_directories(KEMStructuredASCII PRIVATE ${ZLIB_INCLUDE_DIRS}>) + target_link_libraries (KEMStructuredASCII PRIVATE ZLIB::ZLIB) else (KEMField_USE_ZLIB) -target_link_libraries (KEMStructuredASCII) + target_link_libraries (KEMStructuredASCII) endif (KEMField_USE_ZLIB) kasper_install_headers (${STRUCTUREDASCII_HEADERFILES}) diff --git a/KEMField/Source/Interface/BoundaryIntegrators/Electric/CMakeLists.txt b/KEMField/Source/Interface/BoundaryIntegrators/Electric/CMakeLists.txt index 2569ca29b..1becb6819 100644 --- a/KEMField/Source/Interface/BoundaryIntegrators/Electric/CMakeLists.txt +++ b/KEMField/Source/Interface/BoundaryIntegrators/Electric/CMakeLists.txt @@ -3,38 +3,47 @@ # header files set( ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_HEADER_BASENAMES - KElectrostaticBoundaryIntegratorPolicy.hh + KElectrostaticBoundaryIntegratorPolicy.hh ) set( ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/include ) + foreach( BASENAME ${ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_HEADER_BASENAMES} ) - list( APPEND ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_HEADER_FILENAMES ${ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_HEADER_PATH}/${BASENAME} ) + list( APPEND ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_HEADER_FILENAMES ${ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files set( ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_SOURCE_BASENAMES - KElectrostaticBoundaryIntegratorPolicy.cc + KElectrostaticBoundaryIntegratorPolicy.cc ) set( ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/src + ${CMAKE_CURRENT_SOURCE_DIR}/src ) foreach( BASENAME ${ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_SOURCE_BASENAMES} ) - list( APPEND ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_SOURCE_FILENAMES ${ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_SOURCE_PATH}/${BASENAME} ) + list( APPEND ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_SOURCE_FILENAMES ${ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) # library -kasper_internal_include_directories( ${ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_HEADER_PATH} ) -add_library( KEMFieldElectricBoundaryIntegrators SHARED ${ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_SOURCE_FILENAMES} ${ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_HEADER_FILENAMES} ) -set_target_properties( KEMFieldElectricBoundaryIntegrators PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) -target_link_libraries( KEMFieldElectricBoundaryIntegrators - KEMElectrostaticBoundaryIntegrals - KEMFieldExceptions +add_library( KEMFieldElectricBoundaryIntegrators SHARED + ${ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_SOURCE_FILENAMES} ${ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_HEADER_FILENAMES} ) +#set_target_properties( KEMFieldElectricBoundaryIntegrators PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) + +target_include_directories(KEMFieldElectricBoundaryIntegrators + PUBLIC $ $) +target_link_libraries( KEMFieldElectricBoundaryIntegrators + PUBLIC + KEMElectrostaticBoundaryIntegrals + KEMFieldExceptions ) +if(KEMField_USE_OPENCL) + target_link_libraries(KEMFieldElectricBoundaryIntegrators PUBLIC KEMOpenCLPlugin) +endif(KEMField_USE_OPENCL) + # install kasper_install_headers( ${ELECTRICBOUNDARYINTEGRATOR_ELECTRIC_HEADER_FILENAMES} ) kasper_install_libraries( KEMFieldElectricBoundaryIntegrators ) diff --git a/KEMField/Source/Interface/ChargeDensitySolvers/Electric/CMakeLists.txt b/KEMField/Source/Interface/ChargeDensitySolvers/Electric/CMakeLists.txt index db73dfb90..fb062a6e4 100644 --- a/KEMField/Source/Interface/ChargeDensitySolvers/Electric/CMakeLists.txt +++ b/KEMField/Source/Interface/ChargeDensitySolvers/Electric/CMakeLists.txt @@ -17,6 +17,7 @@ set( CHARGEDENSITYSOLVER_ELECTRIC_HEADER_BASENAMES set( CHARGEDENSITYSOLVER_ELECTRIC_HEADER_PATH ${CMAKE_CURRENT_SOURCE_DIR}/include ) + foreach( BASENAME ${CHARGEDENSITYSOLVER_ELECTRIC_HEADER_BASENAMES} ) list( APPEND CHARGEDENSITYSOLVER_ELECTRIC_HEADER_FILENAMES ${CHARGEDENSITYSOLVER_ELECTRIC_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) @@ -41,20 +42,33 @@ foreach( BASENAME ${CHARGEDENSITYSOLVER_ELECTRIC_SOURCE_BASENAMES} ) endforeach( BASENAME ) # library -kasper_internal_include_directories( ${CHARGEDENSITYSOLVER_ELECTRIC_HEADER_PATH} ) -add_library( KEMFieldChargeDensitySolvers SHARED ${CHARGEDENSITYSOLVER_ELECTRIC_SOURCE_FILENAMES} ${CHARGEDENSITYSOLVER_ELECTRIC_HEADER_FILENAMES} ) -set_target_properties( KEMFieldChargeDensitySolvers PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) +add_library( KEMFieldChargeDensitySolvers SHARED + ${CHARGEDENSITYSOLVER_ELECTRIC_SOURCE_FILENAMES} ${CHARGEDENSITYSOLVER_ELECTRIC_HEADER_FILENAMES}) +#set_target_properties( KEMFieldChargeDensitySolvers PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) + +target_include_directories(KEMFieldChargeDensitySolvers + PUBLIC $ $) target_link_libraries( KEMFieldChargeDensitySolvers - ${KGeoBag_LIBRARIES} - KEMElectrostaticBoundaryIntegrals - KEMFieldElectricBoundaryIntegrators - KEMFileManipulation - KEMFieldExceptions - KEMHashGenerator - KEMLinearAlgebraSolvers - KFMUtility + PUBLIC + KEMFieldElectricBoundaryIntegrators + KEMFileManipulation + KEMLinearAlgebraSolvers + KEMLinearAlgebraVisitors + KFMUtility ) +if(KEMField_USE_ROOT) + target_link_libraries(KEMFieldChargeDensitySolvers PUBLIC KEMRootPlugin) +endif(KEMField_USE_ROOT) + +if(KEMField_USE_OPENCL) + target_link_libraries(KEMFieldChargeDensitySolvers PUBLIC KEMOpenCLPlugin) +endif(KEMField_USE_OPENCL) + +if(KEMField_USE_VTK) + target_link_libraries(KEMFieldChargeDensitySolvers PUBLIC KEMVTKPlugin) +endif(KEMField_USE_VTK) + # install kasper_install_headers( ${CHARGEDENSITYSOLVER_ELECTRIC_HEADER_FILENAMES} ) kasper_install_libraries( KEMFieldChargeDensitySolvers ) diff --git a/KEMField/Source/Interface/FieldSolvers/Electric/CMakeLists.txt b/KEMField/Source/Interface/FieldSolvers/Electric/CMakeLists.txt index 03be8d032..aa11220bd 100644 --- a/KEMField/Source/Interface/FieldSolvers/Electric/CMakeLists.txt +++ b/KEMField/Source/Interface/FieldSolvers/Electric/CMakeLists.txt @@ -4,71 +4,56 @@ # header files set( FIELDSOLVER_ELECTRIC_HEADER_BASENAMES KElectricFastMultipoleFieldSolver.hh - KElectricFieldSolver.hh - KElectricZHFieldSolver.hh - KIntegratingElectrostaticFieldSolver.hh + KElectricFieldSolver.hh + KElectricZHFieldSolver.hh + KIntegratingElectrostaticFieldSolver.hh ) set( FIELDSOLVER_ELECTRIC_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/include ) + foreach( BASENAME ${FIELDSOLVER_ELECTRIC_HEADER_BASENAMES} ) - list( APPEND FIELDSOLVER_ELECTRIC_HEADER_FILENAMES ${FIELDSOLVER_ELECTRIC_HEADER_PATH}/${BASENAME} ) + list( APPEND FIELDSOLVER_ELECTRIC_HEADER_FILENAMES ${FIELDSOLVER_ELECTRIC_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files set( FIELDSOLVER_ELECTRIC_SOURCE_BASENAMES KElectricFastMultipoleFieldSolver.cc - KElectricZHFieldSolver.cc - KIntegratingElectrostaticFieldSolver.cc + KElectricZHFieldSolver.cc + KIntegratingElectrostaticFieldSolver.cc ) set( FIELDSOLVER_ELECTRIC_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/src + ${CMAKE_CURRENT_SOURCE_DIR}/src ) foreach( BASENAME ${FIELDSOLVER_ELECTRIC_SOURCE_BASENAMES} ) - list( APPEND FIELDSOLVER_ELECTRIC_SOURCE_FILENAMES ${FIELDSOLVER_ELECTRIC_SOURCE_PATH}/${BASENAME} ) + list( APPEND FIELDSOLVER_ELECTRIC_SOURCE_FILENAMES ${FIELDSOLVER_ELECTRIC_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) -# link libraries -set (FIELDSOLVER_ELECTRIC_LINK_LIBRARIES - KEMZHSolver - KEMZHGenerator - KFMElectrostatics - KFMInterfaceFieldSolvers - KEMHashGenerator - KEMCore - KEMFieldElectricBoundaryIntegrators - KEMElectrostaticBoundaryIntegrals - KEMFieldExceptions +# library +add_library( KEMElectricFieldSolvers SHARED + ${FIELDSOLVER_ELECTRIC_SOURCE_FILENAMES} ${FIELDSOLVER_ELECTRIC_HEADER_FILENAMES} ) +target_include_directories(KEMElectricFieldSolvers + PUBLIC $ $) +target_link_libraries( KEMElectricFieldSolvers + PUBLIC + KEMCore + KEMZHSolver + KFMInterfaceFieldSolvers + KEMFieldElectricBoundaryIntegrators + KEMElectrostaticBoundaryIntegrals ) -if (${PROJECT_NAME}_USE_OPENCL) - kasper_external_include_directories( ${OPENCL_INCLUDE_DIRS} ) - list (APPEND FIELDSOLVER_ELECTRIC_LINK_LIBRARIES - KEMOpenCLPlugin - ) -endif (${PROJECT_NAME}_USE_OPENCL) - -if (${PROJECT_NAME}_USE_MPI) - list (APPEND FIELDSOLVER_ELECTRIC_LINK_LIBRARIES - KEMCore #for MPIInterface.hh - ) -endif(${PROJECT_NAME}_USE_MPI) +if(KEMField_USE_OPENCL) + target_link_libraries(KEMElectricFieldSolvers PUBLIC KEMOpenCLPlugin) +endif(KEMField_USE_OPENCL) -if (${PROJECT_NAME}_USE_VTK) - list (APPEND FIELDSOLVER_ELECTRIC_LINK_LIBRARIES - KEMVTKPlugin - ) -endif (${PROJECT_NAME}_USE_VTK) +if(KEMField_USE_VTK) + target_link_libraries(KEMElectricFieldSolvers PUBLIC KEMVTKPlugin) +endif(KEMField_USE_VTK) -# library -kasper_internal_include_directories( ${FIELDSOLVER_ELECTRIC_HEADER_PATH} ) -add_library( KEMElectricFieldSolvers SHARED ${FIELDSOLVER_ELECTRIC_SOURCE_FILENAMES} ${FIELDSOLVER_ELECTRIC_HEADER_FILENAMES} ) -set_target_properties( KEMElectricFieldSolvers PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) -target_link_libraries( KEMElectricFieldSolvers - ${FIELDSOLVER_ELECTRIC_LINK_LIBRARIES} -) +#set_target_properties( KEMElectricFieldSolvers PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) # install kasper_install_headers( ${FIELDSOLVER_ELECTRIC_HEADER_FILENAMES} ) diff --git a/KEMField/Source/Interface/FieldSolvers/Magnetic/CMakeLists.txt b/KEMField/Source/Interface/FieldSolvers/Magnetic/CMakeLists.txt index 87967924b..a1c1de982 100644 --- a/KEMField/Source/Interface/FieldSolvers/Magnetic/CMakeLists.txt +++ b/KEMField/Source/Interface/FieldSolvers/Magnetic/CMakeLists.txt @@ -9,10 +9,11 @@ set( FIELDSOLVER_MAGNETIC_HEADER_BASENAMES ) set( FIELDSOLVER_MAGNETIC_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/include ) + foreach( BASENAME ${FIELDSOLVER_MAGNETIC_HEADER_BASENAMES} ) - list( APPEND FIELDSOLVER_MAGNETIC_HEADER_FILENAMES ${FIELDSOLVER_MAGNETIC_HEADER_PATH}/${BASENAME} ) + list( APPEND FIELDSOLVER_MAGNETIC_HEADER_FILENAMES ${FIELDSOLVER_MAGNETIC_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files @@ -22,33 +23,24 @@ set( FIELDSOLVER_MAGNETIC_SOURCE_BASENAMES ) set( FIELDSOLVER_MAGNETIC_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/src + ${CMAKE_CURRENT_SOURCE_DIR}/src ) foreach( BASENAME ${FIELDSOLVER_MAGNETIC_SOURCE_BASENAMES} ) - list( APPEND FIELDSOLVER_MAGNETIC_SOURCE_FILENAMES ${FIELDSOLVER_MAGNETIC_SOURCE_PATH}/${BASENAME} ) + list( APPEND FIELDSOLVER_MAGNETIC_SOURCE_FILENAMES ${FIELDSOLVER_MAGNETIC_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) -# link libraries -set (FIELDSOLVER_MAGNETIC_LINK_LIBRARIES - KEMElectromagnets - KEMZHSolver - KEMHashGenerator - KEMCore - KEMFileManipulation - KEMIO - KEMStructuredASCII - ${GSL_LIBRARIES} - ${OPENCL_LIBRARIES} -) - # library -kasper_internal_include_directories( ${FIELDSOLVER_MAGNETIC_HEADER_PATH} ) -add_library( KEMMagneticFieldSolvers SHARED ${FIELDSOLVER_MAGNETIC_SOURCE_FILENAMES} ${FIELDSOLVER_MAGNETIC_HEADER_FILENAMES} ) -set_target_properties( KEMMagneticFieldSolvers PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) -target_link_libraries( KEMMagneticFieldSolvers - ${FIELDSOLVER_MAGNETIC_LINK_LIBRARIES} +add_library( KEMMagneticFieldSolvers SHARED + ${FIELDSOLVER_MAGNETIC_SOURCE_FILENAMES} ${FIELDSOLVER_MAGNETIC_HEADER_FILENAMES} ) +target_include_directories(KEMMagneticFieldSolvers + PUBLIC $ $) +target_link_libraries( KEMMagneticFieldSolvers + PUBLIC + KEMElectromagnets + KEMZHSolver ) +#set_target_properties( KEMMagneticFieldSolvers PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) # install kasper_install_headers( ${FIELDSOLVER_MAGNETIC_HEADER_FILENAMES} ) diff --git a/KEMField/Source/Interface/Fields/Electric/CMakeLists.txt b/KEMField/Source/Interface/Fields/Electric/CMakeLists.txt index 03e686de8..2876d25db 100644 --- a/KEMField/Source/Interface/Fields/Electric/CMakeLists.txt +++ b/KEMField/Source/Interface/Fields/Electric/CMakeLists.txt @@ -17,10 +17,11 @@ set( FIELDS_ELECTRIC_HEADER_BASENAMES ) set( FIELDS_ELECTRIC_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/include ) + foreach( BASENAME ${FIELDS_ELECTRIC_HEADER_BASENAMES} ) - list( APPEND FIELDS_ELECTRIC_HEADER_FILENAMES ${FIELDS_ELECTRIC_HEADER_PATH}/${BASENAME} ) + list( APPEND FIELDS_ELECTRIC_HEADER_FILENAMES ${FIELDS_ELECTRIC_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files @@ -37,19 +38,28 @@ set( FIELDS_ELECTRIC_SOURCE_BASENAMES ) set( FIELDS_ELECTRIC_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/src + ${CMAKE_CURRENT_SOURCE_DIR}/src ) foreach( BASENAME ${FIELDS_ELECTRIC_SOURCE_BASENAMES} ) - list( APPEND FIELDS_ELECTRIC_SOURCE_FILENAMES ${FIELDS_ELECTRIC_SOURCE_PATH}/${BASENAME} ) + list( APPEND FIELDS_ELECTRIC_SOURCE_FILENAMES ${FIELDS_ELECTRIC_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) # library -kasper_internal_include_directories( ${FIELDS_ELECTRIC_HEADER_PATH} ) -add_library( KEMFieldsElectric SHARED ${FIELDS_ELECTRIC_SOURCE_FILENAMES} ${FIELDS_ELECTRIC_HEADER_FILENAMES} ) -set_target_properties( KEMFieldsElectric PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) +add_library( KEMFieldsElectric SHARED + ${FIELDS_ELECTRIC_SOURCE_FILENAMES} ${FIELDS_ELECTRIC_HEADER_FILENAMES} ) +#set_target_properties( KEMFieldsElectric PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) + +target_include_directories(KEMFieldsElectric + PUBLIC $ $) target_link_libraries( KEMFieldsElectric - KEMFieldChargeDensitySolvers - KEMFieldsMagnetic + PUBLIC + Kommon + KEMMath + KEMElectricFieldSolvers + KEMFieldChargeDensitySolvers + # KEMFieldElectricBoundaryIntegrators + KEMFieldsMagnetic # for induced fields + KGeoBagCore ) # install diff --git a/KEMField/Source/Interface/Fields/Magnetic/CMakeLists.txt b/KEMField/Source/Interface/Fields/Magnetic/CMakeLists.txt index 320dacf0c..849214026 100644 --- a/KEMField/Source/Interface/Fields/Magnetic/CMakeLists.txt +++ b/KEMField/Source/Interface/Fields/Magnetic/CMakeLists.txt @@ -13,10 +13,11 @@ set (FIELDS_MAGNETIC_HEADER_BASENAMES ) set( FIELDS_MAGNETIC_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/include ) + foreach( BASENAME ${FIELDS_MAGNETIC_HEADER_BASENAMES} ) - list( APPEND FIELDS_MAGNETIC_HEADER_FILENAMES ${FIELDS_MAGNETIC_HEADER_PATH}/${BASENAME} ) + list( APPEND FIELDS_MAGNETIC_HEADER_FILENAMES ${FIELDS_MAGNETIC_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files @@ -29,19 +30,28 @@ set( FIELDS_MAGNETIC_SOURCE_BASENAMES ) set( FIELDS_MAGNETIC_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/src + ${CMAKE_CURRENT_SOURCE_DIR}/src ) foreach( BASENAME ${FIELDS_MAGNETIC_SOURCE_BASENAMES} ) - list( APPEND FIELDS_MAGNETIC_SOURCE_FILENAMES ${FIELDS_MAGNETIC_SOURCE_PATH}/${BASENAME} ) + list( APPEND FIELDS_MAGNETIC_SOURCE_FILENAMES ${FIELDS_MAGNETIC_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) # library -kasper_internal_include_directories( ${FIELDS_MAGNETIC_HEADER_PATH} ) -add_library( KEMFieldsMagnetic SHARED ${FIELDS_MAGNETIC_SOURCE_FILENAMES} ${FIELDS_MAGNETIC_HEADER_FILENAMES} ) -set_target_properties( KEMFieldsMagnetic PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) +add_library( KEMFieldsMagnetic SHARED + ${FIELDS_MAGNETIC_SOURCE_FILENAMES} ${FIELDS_MAGNETIC_HEADER_FILENAMES} ) +#set_target_properties( KEMFieldsMagnetic PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) + +target_include_directories(KEMFieldsMagnetic + PUBLIC $ $) target_link_libraries( KEMFieldsMagnetic - KEMFieldChargeDensitySolvers - KEMMath KEMCore ${Kommon_LIBRARIES} ${GSL_LIBRARIES} + PUBLIC + Kommon + KEMCore + KEMMath + KEMFieldExceptions + KEMFileManipulation + KEMMagneticFieldSolvers + KEMZHSolver ) # install diff --git a/KEMField/Source/Interface/KGeoBag/CMakeLists.txt b/KEMField/Source/Interface/KGeoBag/CMakeLists.txt index 334bc6742..0eb5308ae 100644 --- a/KEMField/Source/Interface/KGeoBag/CMakeLists.txt +++ b/KEMField/Source/Interface/KGeoBag/CMakeLists.txt @@ -1,36 +1,40 @@ # CMakeLists for KEMField/Interface/KGeoBag # T.J. Corona, D. Hilk - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - - set (KGEOBAGINTERFACE_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KGElectrostaticBoundaryField.hh +set (KGEOBAGINTERFACE_HEADERFILES + ${CMAKE_CURRENT_SOURCE_DIR}/include/KGElectrostaticBoundaryField.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KGBEM.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KGBEMConverter.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KGElectromagnet.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KGElectromagnetConverter.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KGStaticElectromagnetField.hh - ) +) - set (KGEOBAGINTERFACE_SOURCEFILES +set (KGEOBAGINTERFACE_SOURCEFILES ${CMAKE_CURRENT_SOURCE_DIR}/src/KGElectrostaticBoundaryField.cc ${CMAKE_CURRENT_SOURCE_DIR}/src/KGBEM.cc ${CMAKE_CURRENT_SOURCE_DIR}/src/KGBEMConverter.cc ${CMAKE_CURRENT_SOURCE_DIR}/src/KGElectromagnet.cc ${CMAKE_CURRENT_SOURCE_DIR}/src/KGElectromagnetConverter.cc ${CMAKE_CURRENT_SOURCE_DIR}/src/KGStaticElectromagnetField.cc - ) +) + +add_library (KGeoBagInterface SHARED + ${KGEOBAGINTERFACE_SOURCEFILES} ${KGEOBAGINTERFACE_HEADERFILES}) +target_include_directories(KGeoBagInterface + PUBLIC $ $) +target_link_libraries (KGeoBagInterface + PUBLIC + KEMSurfaces + KEMFieldsElectric + KEMFieldsMagnetic + KEMElectromagnets + KGeoBagAxialMesh + KGeoBagDiscreteRotationalMesh + KGeoBagMesh +) - add_library (KGeoBagInterface SHARED ${KGEOBAGINTERFACE_SOURCEFILES} ${KGEOBAGINTERFACE_HEADERFILES}) - target_link_libraries (KGeoBagInterface - KEMSurfaces - KEMFieldsElectric - KEMFieldsMagnetic - KEMElectromagnets - ${GSL_LIBRARIES} - ${OPENCL_LIBRARIES} - ${KGeoBag_LIBRARIES} - ) +target_compile_definitions( KGeoBagInterface PUBLIC KEMFIELD_USE_KGEOBAG ) - kasper_install_headers (${KGEOBAGINTERFACE_HEADERFILES}) - kasper_install_libraries (KGeoBagInterface) +kasper_install_headers (${KGEOBAGINTERFACE_HEADERFILES}) +kasper_install_libraries (KGeoBagInterface) diff --git a/KEMField/Source/Interface/KGeoBag/include/KGElectrostaticBoundaryField.hh b/KEMField/Source/Interface/KGeoBag/include/KGElectrostaticBoundaryField.hh index c953fd35d..cda4ed114 100644 --- a/KEMField/Source/Interface/KGeoBag/include/KGElectrostaticBoundaryField.hh +++ b/KEMField/Source/Interface/KGeoBag/include/KGElectrostaticBoundaryField.hh @@ -41,6 +41,8 @@ class KGElectrostaticBoundaryField : public KElectrostaticBoundaryField void SetSymmetry(const Symmetry& aSymmetry); KSmartPointer GetConverter(); + const std::vector& GetSurfaces() const { return fSurfaces; } + const std::vector& GetSpaces() const { return fSpaces; } private: double PotentialCore(const KPosition& P) const override; diff --git a/KEMField/Source/Interface/KGeoBag/include/KGStaticElectromagnetField.hh b/KEMField/Source/Interface/KGeoBag/include/KGStaticElectromagnetField.hh index 6a48d7b74..a3e9dbf01 100644 --- a/KEMField/Source/Interface/KGeoBag/include/KGStaticElectromagnetField.hh +++ b/KEMField/Source/Interface/KGeoBag/include/KGStaticElectromagnetField.hh @@ -1,5 +1,5 @@ /* - * KGElectrostaticBoundaryField.hh + * KGStaticElectromagnetField.hh * * Created on: 25 Mar 2016 * Author: wolfgang @@ -33,6 +33,9 @@ class KGStaticElectromagnetField : public KStaticElectromagnetField KSmartPointer GetConverter(); + const std::vector& GetSurfaces() const { return fSurfaces; } + const std::vector& GetSpaces() const { return fSpaces; } + private: void InitializeCore() override; diff --git a/KEMField/Source/LinearAlgebra/Core/CMakeLists.txt b/KEMField/Source/LinearAlgebra/Core/CMakeLists.txt index 7d6d4777d..7d715acbb 100644 --- a/KEMField/Source/LinearAlgebra/Core/CMakeLists.txt +++ b/KEMField/Source/LinearAlgebra/Core/CMakeLists.txt @@ -1,15 +1,18 @@ # CMakeLists for KEMField/LinearAlgebra/Core # Author: T.J. Corona -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (LINEARALGEBRACORE_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KMatrix.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSimpleMatrix.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSquareMatrix.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSimpleSquareMatrix.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KVector.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSimpleVector.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KMatrix.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSimpleMatrix.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSquareMatrix.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSimpleSquareMatrix.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KVector.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSimpleVector.hh ) +add_library(KEMLinearAlgebraCore INTERFACE) +target_include_directories(KEMLinearAlgebraCore + INTERFACE $ $) + kasper_install_headers (${LINEARALGEBRACORE_HEADERFILES}) +kasper_install_libraries (KEMLinearAlgebraCore) diff --git a/KEMField/Source/LinearAlgebra/Preconditioners/CMakeLists.txt b/KEMField/Source/LinearAlgebra/Preconditioners/CMakeLists.txt index 13c3cf231..af2244c5f 100644 --- a/KEMField/Source/LinearAlgebra/Preconditioners/CMakeLists.txt +++ b/KEMField/Source/LinearAlgebra/Preconditioners/CMakeLists.txt @@ -1,5 +1,3 @@ -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (PRECONDITIONER_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KPreconditioner.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KIdentityPreconditioner.hh @@ -8,5 +6,10 @@ set (PRECONDITIONER_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KImplicitKrylovPreconditioner.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KMatrixPreconditioner.hh ) +add_library(KEMLinearAlgebraPreconditioner INTERFACE) +target_include_directories(KEMLinearAlgebraPreconditioner + INTERFACE $ $) +target_link_libraries(KEMLinearAlgebraPreconditioner INTERFACE KEMLinearAlgebraVisitors) kasper_install_headers (${PRECONDITIONER_HEADERFILES}) +kasper_install_libraries (KEMLinearAlgebraPreconditioner) diff --git a/KEMField/Source/LinearAlgebra/Solvers/CMakeLists.txt b/KEMField/Source/LinearAlgebra/Solvers/CMakeLists.txt index 8f3907901..544b080b6 100644 --- a/KEMField/Source/LinearAlgebra/Solvers/CMakeLists.txt +++ b/KEMField/Source/LinearAlgebra/Solvers/CMakeLists.txt @@ -1,57 +1,53 @@ # CMakeLists for KEMField/LinearAlgebra/Solvers # Author: T.J. Corona -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (LINEARALGEBRASOLVERS_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KIterativeSolver.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KGaussSeidel.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KGaussSeidel_SingleThread.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KGaussianElimination.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KRobinHood.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KRobinHood_SingleThread.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KMultiElementRobinHood.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KMultiElementRobinHood_SingleThread.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSuccessiveSubspaceCorrection.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSuccessiveSubspaceCorrection_SingleThread.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KIterativeKrylovSolver.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KKrylovSolverConfiguration.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KKrylovSolverFactory.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSimpleIterativeKrylovSolver.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KPreconditionedIterativeKrylovSolver.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KGeneralizedMinimalResidual.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KGeneralizedMinimalResidualState.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KPreconditionedGeneralizedMinimalResidual.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KPreconditionedGeneralizedMinimalResidualState.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KBiconjugateGradientStabilized.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KBiconjugateGradientStabilizedState.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KPreconditionedBiconjugateGradientStabilized.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSVDSolver.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KProjectionSolver.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KIterativeSolver.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KGaussSeidel.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KGaussSeidel_SingleThread.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KGaussianElimination.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KRobinHood.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KRobinHood_SingleThread.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KMultiElementRobinHood.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KMultiElementRobinHood_SingleThread.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSuccessiveSubspaceCorrection.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSuccessiveSubspaceCorrection_SingleThread.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KIterativeKrylovSolver.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KKrylovSolverConfiguration.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KKrylovSolverFactory.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSimpleIterativeKrylovSolver.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KPreconditionedIterativeKrylovSolver.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KGeneralizedMinimalResidual.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KGeneralizedMinimalResidualState.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KPreconditionedGeneralizedMinimalResidual.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KPreconditionedGeneralizedMinimalResidualState.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KBiconjugateGradientStabilized.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KBiconjugateGradientStabilizedState.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KPreconditionedBiconjugateGradientStabilized.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSVDSolver.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KProjectionSolver.hh +) +if (KEMField_USE_MPI) + list (APPEND LINEARALGEBRASOLVERS_HEADERFILES + ${CMAKE_CURRENT_SOURCE_DIR}/include/KGaussSeidel_MPI.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KRobinHood_MPI.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KGeneralizedMinimalResidual_MPI.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KPreconditionedGeneralizedMinimalResidual_MPI.hh ) - if (${PROJECT_NAME}_USE_MPI) - list (APPEND LINEARALGEBRASOLVERS_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KGaussSeidel_MPI.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KRobinHood_MPI.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KGeneralizedMinimalResidual_MPI.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KPreconditionedGeneralizedMinimalResidual_MPI.hh - ) - endif (${PROJECT_NAME}_USE_MPI) - +endif (KEMField_USE_MPI) + set( LINEARALGEBRASOLVERS_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/src/KKrylovSolverConfiguration.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KKrylovSolverConfiguration.cc ) # library -add_library( KEMLinearAlgebraSolvers SHARED ${LINEARALGEBRASOLVERS_SOURCEFILES} ${LINEARALGEBRASOLVERS_HEADERFILES} ) -set_target_properties( KEMLinearAlgebraSolvers PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) -target_link_libraries( KEMLinearAlgebraSolvers - ${LINEARALGEBRASOLVERS_LIBRARIES} -) +add_library( KEMLinearAlgebraSolvers SHARED + ${LINEARALGEBRASOLVERS_SOURCEFILES} ${LINEARALGEBRASOLVERS_HEADERFILES} ) +target_include_directories(KEMLinearAlgebraSolvers + PUBLIC $ $) +target_link_libraries (KEMLinearAlgebraSolvers) +#set_target_properties( KEMLinearAlgebraSolvers PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) # install kasper_install_headers (${LINEARALGEBRASOLVERS_HEADERFILES}) kasper_install_libraries( KEMLinearAlgebraSolvers ) - - - diff --git a/KEMField/Source/LinearAlgebra/Solvers/include/KIterativeSolver.hh b/KEMField/Source/LinearAlgebra/Solvers/include/KIterativeSolver.hh index 8786b72cf..df2329d90 100644 --- a/KEMField/Source/LinearAlgebra/Solvers/include/KIterativeSolver.hh +++ b/KEMField/Source/LinearAlgebra/Solvers/include/KIterativeSolver.hh @@ -126,15 +126,16 @@ template bool KIterativeSolver::Terminate() template void KIterativeSolver::AcceptVisitors() { - for (typename std::vector::const_iterator it = fVisitors.begin(); it != fVisitors.end(); ++it) + for (typename std::vector::const_iterator it = fVisitors.begin(); it != fVisitors.end(); ++it) { if (Iteration() % (*it)->Interval() == 0) (*it)->Visit(*this); + } } template class KIterationDisplay : public KIterativeSolver::Visitor { public: - KIterationDisplay() : fPrefix(""), fCarriageReturn(true) + KIterationDisplay() : fPrefix(""), fCarriageReturn(false) { KIterativeSolver::Visitor::Interval(1); } @@ -154,20 +155,25 @@ template class KIterationDisplay : public KIterativeSolver void KIterationDisplay::Initialize(KIterativeSolver& solver) { - kem_cout() << fPrefix << "Beginning iterative solve with target residual norm " << solver.Tolerance() + kem_cout(eNormal) << fPrefix << "Beginning iterative solve with target residual norm " << solver.Tolerance() << " and dimension " << solver.Dimension() << eom; } template void KIterationDisplay::Visit(KIterativeSolver& solver) { - kem_cout() << fPrefix << "Iteration, |Residual|: " << solver.Iteration() << ", " << solver.ResidualNorm() + kem_cout(eNormal) << fPrefix << "Iteration, |Residual|: " << solver.Iteration() << ", " << solver.ResidualNorm() << (fCarriageReturn ? ret : eom); } template void KIterationDisplay::Finalize(KIterativeSolver& solver) { - kem_cout << fPrefix << "Convergence complete after " << solver.Iteration() - << " iterations, with |Residual|: " << solver.ResidualNorm() << eom; + if (!std::isfinite(solver.ResidualNorm()) || solver.ResidualNorm() == 0) { + kem_cout(eError) << fPrefix << "Convergence incomplete after " << solver.Iteration() + << " iterations, with |Residual|: " << solver.ResidualNorm() << eom; + } + + kem_cout(eNormal) << fPrefix << "Convergence complete after " << solver.Iteration() + << " iterations, with |Residual|: " << solver.ResidualNorm() << eom; } } // namespace KEMField diff --git a/KEMField/Source/LinearAlgebra/Solvers/include/KMultiElementRobinHood.hh b/KEMField/Source/LinearAlgebra/Solvers/include/KMultiElementRobinHood.hh index c1f58d848..b423fce48 100644 --- a/KEMField/Source/LinearAlgebra/Solvers/include/KMultiElementRobinHood.hh +++ b/KEMField/Source/LinearAlgebra/Solvers/include/KMultiElementRobinHood.hh @@ -89,9 +89,14 @@ void KMultiElementRobinHood::Solve(const Matrix& A, Ve trait.FindResidual(); if (subIteration == fResidualCheckInterval) { subIteration = 0; + double residualNorm; + trait.FindResidualNorm(residualNorm); + if (residualNorm > 1e100) + kem_cout(eError) << "Iterative solve failed to converge, current |Residual|: " << residualNorm << eom; + else if (this->fIteration > 0 && residualNorm > this->fResidualNorm*2.) + kem_cout(eWarning) << "Convergence problem, |Residual| increased by " << (100*residualNorm/this->fResidualNorm) << "%" << eom; + this->fResidualNorm = residualNorm; this->fIteration++; - trait.FindResidualNorm(this->fResidualNorm); - this->AcceptVisitors(); } trait.IdentifyLargestResidualElements(); diff --git a/KEMField/Source/LinearAlgebra/Solvers/include/KPreconditionedIterativeKrylovSolver.hh b/KEMField/Source/LinearAlgebra/Solvers/include/KPreconditionedIterativeKrylovSolver.hh index b3b0b6bf8..d465eb35e 100644 --- a/KEMField/Source/LinearAlgebra/Solvers/include/KPreconditionedIterativeKrylovSolver.hh +++ b/KEMField/Source/LinearAlgebra/Solvers/include/KPreconditionedIterativeKrylovSolver.hh @@ -132,7 +132,11 @@ void KPreconditionedIterativeKrylovSolver::Solve(const do { solutionUpdated = false; trait.AugmentKrylovSubspace(); - trait.GetResidualNorm(this->fResidualNorm); + double residualNorm; + trait.GetResidualNorm(residualNorm); + if (this->fIteration > 0 && residualNorm > this->fResidualNorm*2.) + kem_cout(eWarning) << "Convergence problem, |Residual| increased by " << (100*residualNorm/this->fResidualNorm) << "%" << eom; + this->fResidualNorm = residualNorm; this->GetRestartCondition()->UpdateProgress(this->fResidualNorm); this->fIteration++; diff --git a/KEMField/Source/LinearAlgebra/Solvers/include/KRobinHood.hh b/KEMField/Source/LinearAlgebra/Solvers/include/KRobinHood.hh index f419ce5bd..595163881 100644 --- a/KEMField/Source/LinearAlgebra/Solvers/include/KRobinHood.hh +++ b/KEMField/Source/LinearAlgebra/Solvers/include/KRobinHood.hh @@ -76,13 +76,20 @@ void KRobinHood::Solve(const Matrix& A, Vector& x, con while (this->fResidualNorm > this->fTolerance && !(this->Terminate())) { subIteration++; trait.FindResidual(); - if (subIteration == fResidualCheckInterval) { + + if (subIteration % fResidualCheckInterval == 0) { subIteration = 0; + double residualNorm; + trait.FindResidualNorm(residualNorm); + if (residualNorm > 1e100) + kem_cout(eError) << "Iterative solve failed to converge, current |Residual|: " << residualNorm << eom; + else if (this->fIteration > 0 && residualNorm > this->fResidualNorm*2.) + kem_cout(eWarning) << "Convergence problem, |Residual| increased by " << (100*residualNorm/this->fResidualNorm) << "%" << eom; + this->fResidualNorm = residualNorm; this->fIteration++; - trait.FindResidualNorm(this->fResidualNorm); - this->AcceptVisitors(); } + trait.IdentifyLargestResidualElement(); trait.ComputeCorrection(); trait.UpdateSolutionApproximation(); diff --git a/KEMField/Source/LinearAlgebra/Solvers/include/KRobinHood_SingleThread.hh b/KEMField/Source/LinearAlgebra/Solvers/include/KRobinHood_SingleThread.hh index 433361e19..883bfb5b7 100644 --- a/KEMField/Source/LinearAlgebra/Solvers/include/KRobinHood_SingleThread.hh +++ b/KEMField/Source/LinearAlgebra/Solvers/include/KRobinHood_SingleThread.hh @@ -2,6 +2,8 @@ #define KROBINHOOD_SINGLETHREAD_DEF #include "KSimpleVector.hh" +#include "KSquareMatrix.hh" +#include "KEMCoreMessage.hh" namespace KEMField { diff --git a/KEMField/Source/LinearAlgebra/Solvers/include/KSimpleIterativeKrylovSolver.hh b/KEMField/Source/LinearAlgebra/Solvers/include/KSimpleIterativeKrylovSolver.hh index 2c967addc..8aa575f89 100644 --- a/KEMField/Source/LinearAlgebra/Solvers/include/KSimpleIterativeKrylovSolver.hh +++ b/KEMField/Source/LinearAlgebra/Solvers/include/KSimpleIterativeKrylovSolver.hh @@ -155,7 +155,13 @@ void KSimpleIterativeKrylovSolver::Solve(const Matrix& do { solutionUpdated = false; trait.AugmentKrylovSubspace(); - trait.GetResidualNorm(this->fResidualNorm); + + double residualNorm; + trait.GetResidualNorm(residualNorm); + if (this->fIteration >0 && residualNorm > this->fResidualNorm*2.) + kem_cout(eWarning) << "Convergence problem, |Residual| increased by " << (100*residualNorm/this->fResidualNorm) << "%" << eom; + this->fResidualNorm = residualNorm; + this->GetRestartCondition()->UpdateProgress(this->fResidualNorm); this->fIteration++; diff --git a/KEMField/Source/LinearAlgebra/Visitors/CMakeLists.txt b/KEMField/Source/LinearAlgebra/Visitors/CMakeLists.txt index 9da8a35ff..c6cdaf2b8 100644 --- a/KEMField/Source/LinearAlgebra/Visitors/CMakeLists.txt +++ b/KEMField/Source/LinearAlgebra/Visitors/CMakeLists.txt @@ -1,20 +1,23 @@ # CMakeLists for KEMField/LinearAlgebra/Visitors # Author: T.J. Corona -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (LINEARALGEBRAVISITORS_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KIterationTracker.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KIterativeStateReader.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KIterativeStateWriter.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KIterativeKrylovStateWriter.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KIterativeKrylovStateReader.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KPreconditionedIterativeKrylovStateWriter.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KPreconditionedIterativeKrylovStateReader.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KResidualVector.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KIterationTerminator.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KIterativeSolverTimer.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KTimeTerminator.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KIterationTracker.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KIterativeStateReader.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KIterativeStateWriter.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KIterativeKrylovStateWriter.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KIterativeKrylovStateReader.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KPreconditionedIterativeKrylovStateWriter.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KPreconditionedIterativeKrylovStateReader.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KResidualVector.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KIterationTerminator.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KIterativeSolverTimer.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KTimeTerminator.hh ) +add_library(KEMLinearAlgebraVisitors INTERFACE) +target_include_directories(KEMLinearAlgebraVisitors + INTERFACE $ $) + kasper_install_headers (${LINEARALGEBRAVISITORS_HEADERFILES}) +kasper_install_libraries (KEMLinearAlgebraVisitors) diff --git a/KEMField/Source/Math/Array/CMakeLists.txt b/KEMField/Source/Math/Array/CMakeLists.txt index 785ac7e77..6fc024491 100644 --- a/KEMField/Source/Math/Array/CMakeLists.txt +++ b/KEMField/Source/Math/Array/CMakeLists.txt @@ -1,8 +1,6 @@ # CMakeLists for KEMField/FastMultipole/Array # Author: J. P. Barrett -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (KFMARRAY_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMArrayMath.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMArrayWrapper.hh @@ -18,4 +16,9 @@ set (KFMARRAY_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMMessaging.hh ) +add_library(KFMArray INTERFACE) +target_include_directories(KFMArray + INTERFACE $ $) + kasper_install_headers (${KFMARRAY_HEADERFILES}) +kasper_install_libraries (KFMArray) diff --git a/KEMField/Source/Math/CMakeLists.txt b/KEMField/Source/Math/CMakeLists.txt index d9fd99e0f..17f50f004 100644 --- a/KEMField/Source/Math/CMakeLists.txt +++ b/KEMField/Source/Math/CMakeLists.txt @@ -1,37 +1,38 @@ # CMakeLists for KEMField/Math # Author: T.J. Corona -if (${PROJECT_NAME}_USE_GSL) - kasper_external_include_directories (${GSL_INCLUDE_DIRS}) - add_cflag(KEMFIELD_USE_GSL) -endif () - -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (MATH_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEllipticIntegrals.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMCoordinateSystem.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMTransformation.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KThreeVector_KEMField.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMStreamableThreeVector.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KThreeMatrix_KEMField.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KGaussianQuadrature.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KGaussLegendreQuadrature.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KShanksTransformation.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEllipticIntegrals.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMCoordinateSystem.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMTransformation.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KThreeVector_KEMField.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMStreamableThreeVector.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KThreeMatrix_KEMField.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KGaussianQuadrature.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KGaussLegendreQuadrature.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KShanksTransformation.hh ) set (MATH_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEllipticIntegrals.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMCoordinateSystem.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KGaussianQuadrature.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KGaussLegendreQuadrature.cc - ) + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEllipticIntegrals.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMCoordinateSystem.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KGaussianQuadrature.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KGaussLegendreQuadrature.cc +) -################################################## +add_library (KEMMath SHARED + ${MATH_SOURCEFILES} ${MATH_HEADERFILES}) +target_include_directories(KEMMath + PUBLIC $ $) +target_link_libraries (KEMMath + PUBLIC + KGeoBagMath +) -add_library (KEMMath SHARED ${MATH_SOURCEFILES} ${MATH_HEADERFILES}) -target_link_libraries (KEMMath KEMCore ${Kommon_LIBRARIES} ${KGeoBag_LIBRARIES} ${GSL_LIBRARIES}) +if(KEMField_USE_GSL) + target_link_libraries(KEMMath PUBLIC GSL::gsl) + target_compile_definitions(KEMMath PUBLIC KEMFIELD_USE_GSL) +endif(KEMField_USE_GSL) kasper_install_headers (${MATH_HEADERFILES}) kasper_install_libraries (KEMMath) - diff --git a/KEMField/Source/Math/Utilities/CMakeLists.txt b/KEMField/Source/Math/Utilities/CMakeLists.txt index c906c15c6..c461e938a 100644 --- a/KEMField/Source/Math/Utilities/CMakeLists.txt +++ b/KEMField/Source/Math/Utilities/CMakeLists.txt @@ -1,21 +1,6 @@ # CMakeLists for KEMField/FastMultipole/Math # Author: J. P. Barrett -if (KEMField_USE_GSL) - find_package(GSL REQUIRED) - kasper_external_include_directories (${GSL_INCLUDE_DIRS}) - add_definitions(-DKEMFIELD_USE_GSL) -endif () - -option (KEMField_USE_FFTW "Use FFTW" OFF) -if (KEMField_USE_FFTW) - find_package(FFTW 3.3.4 REQUIRED) - kasper_external_include_directories (${FFTW_INCLUDE_DIRS}) - add_cflag(KEMFIELD_USE_FFTW) -endif () - -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (MATH_UTILITIES_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMMath.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMBitReversalPermutation.hh @@ -33,7 +18,8 @@ set (MATH_UTILITIES_HEADERFILES ) if(KEMField_USE_FFTW) - set( MATH_UTILITIES_HEADERFILES ${MATH_UTILITIES_HEADERFILES} ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMMultidimensionalFastFourierTransformFFTW.hh ) + set( MATH_UTILITIES_HEADERFILES ${MATH_UTILITIES_HEADERFILES} + ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMMultidimensionalFastFourierTransformFFTW.hh ) endif(KEMField_USE_FFTW) set (MATH_UTILITIES_SOURCEFILES @@ -49,21 +35,25 @@ set (MATH_UTILITIES_SOURCEFILES ${CMAKE_CURRENT_SOURCE_DIR}/src/KFMSquareRootUtilities.cc ) -add_library (KFMMathUtilities SHARED ${MATH_UTILITIES_SOURCEFILES} ${MATH_UTILITIES_HEADERFILES}) +add_library (KFMMathUtilities SHARED + ${MATH_UTILITIES_SOURCEFILES} ${MATH_UTILITIES_HEADERFILES}) +target_include_directories(KFMMathUtilities + PUBLIC $ $) +target_link_libraries (KFMMathUtilities + PUBLIC + KEMCore + KFMArray +) + +if(KEMField_USE_FFTW) + target_link_libraries(KFMMathUtilities PUBLIC ${FFTW_LIBRARIES}) + target_compile_definitions(KFMMathUtilities PUBLIC KEMFIELD_USE_FFTW) +endif(KEMField_USE_FFTW) -if(KASPER_USE_GSL) - if(KEMField_USE_FFTW) - target_link_libraries (KFMMathUtilities KEMCore ${GSL_LIBRARIES} ${FFTW_LIBRARIES}) - else() - target_link_libraries (KFMMathUtilities KEMCore ${GSL_LIBRARIES}) - endif() -else() - if(KEMField_USE_FFTW) - target_link_libraries (KFMMathUtilities KEMCore ${FFTW_LIBRARIES}) - else() - target_link_libraries (KFMMathUtilities KEMCore ) - endif() -endif () +if(KEMField_USE_GSL) + target_link_libraries(KFMMathUtilities PUBLIC GSL::gsl) + target_compile_definitions(KFMMathUtilities PUBLIC KEMFIELD_USE_GSL) +endif(KEMField_USE_GSL) kasper_install_headers (${MATH_UTILITIES_HEADERFILES}) kasper_install_libraries (KFMMathUtilities) diff --git a/KEMField/Source/Math/VectorMath/CMakeLists.txt b/KEMField/Source/Math/VectorMath/CMakeLists.txt index 5f3fd87b5..15315583e 100644 --- a/KEMField/Source/Math/VectorMath/CMakeLists.txt +++ b/KEMField/Source/Math/VectorMath/CMakeLists.txt @@ -1,8 +1,6 @@ # CMakeLists for KEMField/VectorMath # Author: J. P. Barrett -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (VECTORMATH_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KVMFixedArray.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KVMMap.hh @@ -38,10 +36,16 @@ set (VECTORMATH_SOURCEFILES ${CMAKE_CURRENT_SOURCE_DIR}/src/KVMFluxIntegral.cc ) -################################################## - -add_library (KVectorMath SHARED ${VECTORMATH_SOURCEFILES} ${VECTORMATH_HEADERFILES}) -target_link_libraries (KVectorMath KEMMath KFMMathUtilities ${Kommon_LIBRARIES} ${KGeoBag_LIBRARIES}) +add_library (KFMVectorMath SHARED + ${VECTORMATH_SOURCEFILES} ${VECTORMATH_HEADERFILES}) +target_include_directories(KFMVectorMath + PUBLIC $ $) +target_link_libraries (KFMVectorMath + PUBLIC + KEMMath + KFMMathUtilities + KGeoBagMath + ) kasper_install_headers (${VECTORMATH_HEADERFILES}) -kasper_install_libraries (KVectorMath) +kasper_install_libraries (KFMVectorMath) diff --git a/KEMField/Source/Math/VectorMath/include/KVMSpaceLineSegment.hh b/KEMField/Source/Math/VectorMath/include/KVMSpaceLineSegment.hh index 0dab3b990..ca192da26 100644 --- a/KEMField/Source/Math/VectorMath/include/KVMSpaceLineSegment.hh +++ b/KEMField/Source/Math/VectorMath/include/KVMSpaceLineSegment.hh @@ -1,7 +1,7 @@ #ifndef KVMSpaceLineSegment_H #define KVMSpaceLineSegment_H -#include "../../include/KThreeVector_KEMField.hh" +#include "KThreeVector_KEMField.hh" #include #include diff --git a/KEMField/Source/Math/VectorMath/include/KVMSpaceRectangle.hh b/KEMField/Source/Math/VectorMath/include/KVMSpaceRectangle.hh index 7569ae117..f39570b89 100644 --- a/KEMField/Source/Math/VectorMath/include/KVMSpaceRectangle.hh +++ b/KEMField/Source/Math/VectorMath/include/KVMSpaceRectangle.hh @@ -1,7 +1,7 @@ #ifndef KVMSpaceRectangle_H #define KVMSpaceRectangle_H -#include "../../include/KThreeVector_KEMField.hh" +#include "KThreeVector_KEMField.hh" #include #include diff --git a/KEMField/Source/Math/VectorMath/include/KVMSpaceTriangle.hh b/KEMField/Source/Math/VectorMath/include/KVMSpaceTriangle.hh index 1af7bfe1f..27aa95540 100644 --- a/KEMField/Source/Math/VectorMath/include/KVMSpaceTriangle.hh +++ b/KEMField/Source/Math/VectorMath/include/KVMSpaceTriangle.hh @@ -1,7 +1,7 @@ #ifndef KVMSpaceTriangle_H #define KVMSpaceTriangle_H -#include "../../include/KThreeVector_KEMField.hh" +#include "KThreeVector_KEMField.hh" #include #include diff --git a/KEMField/Source/Math/include/KThreeMatrix_KEMField.hh b/KEMField/Source/Math/include/KThreeMatrix_KEMField.hh index a57ebb2f3..54ac1d0d7 100644 --- a/KEMField/Source/Math/include/KThreeMatrix_KEMField.hh +++ b/KEMField/Source/Math/include/KThreeMatrix_KEMField.hh @@ -8,6 +8,7 @@ namespace KEMField { + using KThreeMatrix = KGeoBag::KThreeMatrix; template Stream& operator>>(Stream& s, KThreeMatrix& aThreeMatrix) diff --git a/KEMField/Source/Math/include/KThreeVector_KEMField.hh b/KEMField/Source/Math/include/KThreeVector_KEMField.hh index 2800c5923..51c800336 100644 --- a/KEMField/Source/Math/include/KThreeVector_KEMField.hh +++ b/KEMField/Source/Math/include/KThreeVector_KEMField.hh @@ -11,6 +11,8 @@ namespace KEMField { +using KThreeVector = KGeoBag::KThreeVector; + template Stream& operator>>(Stream& s, KGeoBag::KThreeVector& aThreeVector) { s.PreStreamInAction(aThreeVector); diff --git a/KEMField/Source/Plugins/OpenCL/BoundaryIntegrals/Core/include/KOpenCLBoundaryIntegralMatrix.hh b/KEMField/Source/Plugins/OpenCL/BoundaryIntegrals/Core/include/KOpenCLBoundaryIntegralMatrix.hh index bfbfb1f95..c4df6033b 100644 --- a/KEMField/Source/Plugins/OpenCL/BoundaryIntegrals/Core/include/KOpenCLBoundaryIntegralMatrix.hh +++ b/KEMField/Source/Plugins/OpenCL/BoundaryIntegrals/Core/include/KOpenCLBoundaryIntegralMatrix.hh @@ -24,12 +24,12 @@ class KBoundaryIntegralMatrix> : ~KBoundaryIntegralMatrix() override; - unsigned int Dimension() const + unsigned int Dimension() const override { return fDimension; } - const ValueType& operator()(unsigned int i, unsigned int j) const; + const ValueType& operator()(unsigned int i, unsigned int j) const override; void SetNLocal(int nLocal) const { diff --git a/KEMField/Source/Plugins/OpenCL/CMakeLists.txt b/KEMField/Source/Plugins/OpenCL/CMakeLists.txt index b80bdce9f..034817e61 100644 --- a/KEMField/Source/Plugins/OpenCL/CMakeLists.txt +++ b/KEMField/Source/Plugins/OpenCL/CMakeLists.txt @@ -5,389 +5,350 @@ #is not yet activated. This is because on certain systems we need to specify #the platform id before enabling OpenCL so that header file generator #compiles and runs correctly. -set(${PROJECT_NAME}_OPENCL_PLATFORM "0" CACHE STRING "OpenCL platform ID number.") -mark_as_advanced(FORCE ${PROJECT_NAME}_OPENCL_PLATFORM) -add_cflag(KEMFIELD_OPENCL_PLATFORM=${${PROJECT_NAME}_OPENCL_PLATFORM}) - -set(${PROJECT_NAME}_OPENCL_DEVICE_TYPE "0" CACHE STRING "OpenCL device type; GPU=0, CPU=1, Accelerator=2; Any=-1.") -mark_as_advanced(FORCE ${PROJECT_NAME}_OPENCL_DEVICE_TYPE) -add_cflag(KEMFIELD_OPENCL_DEVICE_TYPE=${${PROJECT_NAME}_OPENCL_DEVICE_TYPE}) - -set(${PROJECT_NAME}_OPENCL_FASTDIELECTRICS "0" CACHE STRING "Choose the check method of Neumann boundary elements in Robin Hood; 0 (check interval equal to Dirichlet elements), 1 (decrease checked accuracy of Neumann elements by 1/20), 2 (counter technique with the function RH_BoundaryRatioExceeded)") -mark_as_advanced(FORCE ${PROJECT_NAME}_OPENCL_FASTDIELECTRICS) -add_cflag(KEMFIELD_FASTDIELECTRICS_VALUE=${${PROJECT_NAME}_OPENCL_FASTDIELECTRICS}) - -cmake_dependent_option (${PROJECT_NAME}_OPENCL_FASTRWG "Activate the fast evaluation of electrostatic boundary integrals in RWG basis if no field point has to be computed on any surface." OFF ${PROJECT_NAME}_USE_OPENCL OFF) -mark_as_advanced(FORCE ${PROJECT_NAME}_OPENCL_FASTRWG) -if (${PROJECT_NAME}_OPENCL_FASTRWG) - add_cflag(KEMFIELD_FASTRWG_VALUE=1) -else (${PROJECT_NAME}_OPENCL_FASTRWG) - add_cflag(KEMFIELD_FASTRWG_VALUE=0) -endif (${PROJECT_NAME}_OPENCL_FASTRWG) - -cmake_dependent_option (${PROJECT_NAME}_OPENCL_FFT_CONST_MEM "Enable use of OpenCL device constant memory by FFT kernel." ON - ${PROJECT_NAME}_USE_OPENCL OFF) -mark_as_advanced(FORCE ${PROJECT_NAME}_OPENCL_FFT_CONST_MEM) -if (${PROJECT_NAME}_OPENCL_FFT_CONST_MEM) - set (${PROJECT_NAME}_OPENCL_CFLAGS ${${PROJECT_NAME}_OPENCL_CFLAGS} -DKEMFIELD_OPENCL_FFT_CONST_MEM) - add_cflag (KEMFIELD_OPENCL_FFT_CONST_MEM) -endif (${PROJECT_NAME}_OPENCL_FFT_CONST_MEM) - -# cmake_dependent_option (${PROJECT_NAME}_OPENCL_USE_DEPRECATED_API "Use deprecated OpenCL 1.1 API" OFF -# ${PROJECT_NAME}_USE_OPENCL OFF) -# mark_as_advanced(FORCE ${PROJECT_NAME}_OPENCL_USE_DEPRECATED_API) -# if (${PROJECT_NAME}_OPENCL_USE_DEPRECATED_API) -# set (${PROJECT_NAME}_OPENCL_CFLAGS ${${PROJECT_NAME}_OPENCL_CFLAGS} -DCL_USE_DEPRECATED_OPENCL_1_1_APIS) -# add_cflag (CL_USE_DEPRECATED_OPENCL_1_1_APIS) -# endif (${PROJECT_NAME}_OPENCL_USE_DEPRECATED_API) - -cmake_dependent_option (${PROJECT_NAME}_OPENCL_USE_CL_VECTOR "Use deprecated cl::vector in place of std::vector" OFF - ${PROJECT_NAME}_USE_OPENCL OFF) -mark_as_advanced(FORCE ${PROJECT_NAME}_OPENCL_USE_CL_VECTOR) -if (${PROJECT_NAME}_OPENCL_USE_CL_VECTOR) - set (${PROJECT_NAME}_OPENCL_CFLAGS ${${PROJECT_NAME}_OPENCL_CFLAGS} -DKEMFIELD_USE_CL_VECTOR) - add_cflag (KEMFIELD_USE_CL_VECTOR) -endif (${PROJECT_NAME}_OPENCL_USE_CL_VECTOR) - -#cmake_dependent_option (${PROJECT_NAME}_OPENCL_INTERNAL_1_1 "Use internally packaged OpenCL 1.1 headers" OFF -# ${PROJECT_NAME}_USE_OPENCL OFF) -#mark_as_advanced(FORCE ${PROJECT_NAME}_OPENCL_INTERNAL_1_1) -#if (${PROJECT_NAME}_OPENCL_INTERNAL_1_1) -# set (${PROJECT_NAME}_OPENCL_TEMP_INCLUDE_DIR_STR \"${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/opencl/1.1\") -# string (REPLACE "\"" "" ${PROJECT_NAME}_OPENCL_TEMP_INCLUDE_DIR_VAR ${${PROJECT_NAME}_OPENCL_TEMP_INCLUDE_DIR_STR} ) -# set (${PROJECT_NAME}_OPENCL_CFLAGS ${${PROJECT_NAME}_OPENCL_CFLAGS} -isystem ${${PROJECT_NAME}_OPENCL_TEMP_INCLUDE_DIR_VAR}) -#endif (${PROJECT_NAME}_OPENCL_INTERNAL_1_1) - -#cmake_dependent_option (${PROJECT_NAME}_OPENCL_INTERNAL_1_2 "Use internally packaged OpenCL 1.2 headers" OFF -# ${PROJECT_NAME}_USE_OPENCL OFF) -#mark_as_advanced(FORCE ${PROJECT_NAME}_OPENCL_INTERNAL_1_2) -#if (${PROJECT_NAME}_OPENCL_INTERNAL_1_2) -# set (${PROJECT_NAME}_OPENCL_TEMP_INCLUDE_DIR_STR \"${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/opencl/1.2\") -# string (REPLACE "\"" "" ${PROJECT_NAME}_OPENCL_TEMP_INCLUDE_DIR_VAR ${${PROJECT_NAME}_OPENCL_TEMP_INCLUDE_DIR_STR} ) -# set (${PROJECT_NAME}_OPENCL_CFLAGS ${${PROJECT_NAME}_OPENCL_CFLAGS} -isystem ${${PROJECT_NAME}_OPENCL_TEMP_INCLUDE_DIR_VAR}) -#endif (${PROJECT_NAME}_OPENCL_INTERNAL_1_2) - -cmake_dependent_option (${PROJECT_NAME}_OPENCL_INTERNAL_2_2 "Use internally packaged OpenCL 2.2 headers" OFF - ${PROJECT_NAME}_USE_OPENCL OFF) -mark_as_advanced(FORCE ${PROJECT_NAME}_OPENCL_INTERNAL_2_2) -if (${PROJECT_NAME}_OPENCL_INTERNAL_2_2) - set (${PROJECT_NAME}_OPENCL_TEMP_INCLUDE_DIR_STR \"${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/opencl/2.2\") - string (REPLACE "\"" "" ${PROJECT_NAME}_OPENCL_TEMP_INCLUDE_DIR_VAR ${${PROJECT_NAME}_OPENCL_TEMP_INCLUDE_DIR_STR} ) - set (${PROJECT_NAME}_OPENCL_CFLAGS ${${PROJECT_NAME}_OPENCL_CFLAGS} -isystem ${${PROJECT_NAME}_OPENCL_TEMP_INCLUDE_DIR_VAR}) -endif (${PROJECT_NAME}_OPENCL_INTERNAL_2_2) - -cmake_dependent_option (${PROJECT_NAME}_OPENCL_INTERNAL_2_2 "Use internally packaged OpenCL 2.2 headers" OFF - ${PROJECT_NAME}_USE_OPENCL OFF) -mark_as_advanced(FORCE ${PROJECT_NAME}_OPENCL_INTERNAL_2_2) -if (${PROJECT_NAME}_OPENCL_INTERNAL_2_2) - set (${PROJECT_NAME}_OPENCL_TEMP_INCLUDE_DIR_STR \"${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/opencl/2.2\") - string (REPLACE "\"" "" ${PROJECT_NAME}_OPENCL_TEMP_INCLUDE_DIR_VAR ${${PROJECT_NAME}_OPENCL_TEMP_INCLUDE_DIR_STR} ) - set (${PROJECT_NAME}_OPENCL_CFLAGS ${${PROJECT_NAME}_OPENCL_CFLAGS} -isystem ${${PROJECT_NAME}_OPENCL_TEMP_INCLUDE_DIR_VAR}) -endif (${PROJECT_NAME}_OPENCL_INTERNAL_2_2) - -option (${PROJECT_NAME}_USE_OPENCL "Use OpenCL via C++ wrapper API." OFF) -if (${PROJECT_NAME}_USE_OPENCL) - - message(STATUS "${PROJECT_NAME} is looking for compatbile OpenCL devices ...") - - # force deactivation of FFTW because it permutes FFT outputs in a different way - # than the native FFT, which leads to incorrect fast multipole response functions - set( KEMField_USE_FFTW OFF CACHE BOOL "(Required)" FORCE) - - find_package (OpenCL REQUIRED) - kasper_external_include_directories(${OpenCL_INCLUDE_DIRS}) - add_cflag (KEMFIELD_USE_OPENCL) - - if(${PROJECT_NAME}_OPENCL_INTERNAL_1_1) - kasper_internal_include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/opencl/1.1) - endif(${PROJECT_NAME}_OPENCL_INTERNAL_1_1) - - if(${PROJECT_NAME}_OPENCL_INTERNAL_1_2) - kasper_internal_include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/opencl/1.2) - endif(${PROJECT_NAME}_OPENCL_INTERNAL_1_2) - - if(${PROJECT_NAME}_OPENCL_INTERNAL_2_2) - kasper_internal_include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/opencl/2.2) - endif(${PROJECT_NAME}_OPENCL_INTERNAL_2_2) - - get_filename_component(OPENCL_LIBDIR ${OpenCL_LIBRARIES} PATH) - - if (APPLE) - execute_process(COMMAND ${CMAKE_CXX_COMPILER} - -D KEMFIELD_OPENCL_PLATFORM=${${PROJECT_NAME}_OPENCL_PLATFORM} - -D KEMFIELD_OPENCL_DEVICE_TYPE=${${PROJECT_NAME}_OPENCL_DEVICE_TYPE} - -o ${CMAKE_BINARY_DIR}/${PROJECT_NAME}/GenerateOpenCLHeader - -I${OpenCL_INCLUDE_DIRS} - ${${PROJECT_NAME}_OPENCL_CFLAGS} - -framework OpenCL - ${SOURCE}/Plugins/OpenCL/Core/src/GenerateOpenCLHeader.cc - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - RESULT_VARIABLE COMPILE_STATUS) - - else (APPLE) - execute_process(COMMAND ${CMAKE_CXX_COMPILER} - -D KEMFIELD_OPENCL_PLATFORM=${${PROJECT_NAME}_OPENCL_PLATFORM} - -D KEMFIELD_OPENCL_DEVICE_TYPE=${${PROJECT_NAME}_OPENCL_DEVICE_TYPE} - -o ${CMAKE_BINARY_DIR}/${PROJECT_NAME}/GenerateOpenCLHeader - -I${OpenCL_INCLUDE_DIRS} - ${${PROJECT_NAME}_OPENCL_CFLAGS} - ${SOURCE}/Plugins/OpenCL/Core/src/GenerateOpenCLHeader.cc - ${OpenCL_LIBRARIES} - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - RESULT_VARIABLE COMPILE_STATUS) - - endif (APPLE) - - if(COMPILE_STATUS AND NOT COMPILE_STATUS EQUAL 0) - message(FATAL_ERROR " *** Could not build \"GenerateOpenCLHeader\" ***\n" - " There was an error compiling an OpenCL program. Please check your config.\n" - " KEMFIELD_OPENCL_PLATFORM=${${PROJECT_NAME}_OPENCL_PLATFORM}\n" - " KEMFIELD_OPENCL_DEVICE_TYPE=${${PROJECT_NAME}_OPENCL_DEVICE_TYPE}") - endif() - - set(OPENCLPLUGIN_GENERATED_HEADER ${CMAKE_BINARY_DIR}/${PROJECT_NAME}/kEMField_opencl_defines.h) - execute_process(COMMAND ${CMAKE_BINARY_DIR}/${PROJECT_NAME}/GenerateOpenCLHeader - OUTPUT_FILE ${OPENCLPLUGIN_GENERATED_HEADER} - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - RESULT_VARIABLE EXEC_STATUS) - - if(EXEC_STATUS AND NOT EXEC_STATUS EQUAL 0) - file(REMOVE ${OPENCLPLUGIN_GENERATED_HEADER}) - message(FATAL_ERROR " *** Could not run \"GenerateOpenCLHeader\" ***\n" - " There was an error generating the OpenCL headers. Please check your config.\n" - " KEMFIELD_OPENCL_PLATFORM=${${PROJECT_NAME}_OPENCL_PLATFORM}\n" - " KEMFIELD_OPENCL_DEVICE_TYPE=${${PROJECT_NAME}_OPENCL_DEVICE_TYPE}") - else() - message(STATUS "OpenCL header was generated: ${OPENCLPLUGIN_GENERATED_HEADER}") - endif() - -#leave this binary around since it is useful for debugging if things go wrong -#execute_process(COMMAND rm GenerateOpenCLHeader WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) - - kasper_internal_include_directories(${CMAKE_BINARY_DIR}/${PROJECT_NAME}) - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Core/include) - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/IO/include) - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Surfaces/include) - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Core/include) - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/include) - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/include) - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/RWG/include) - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/include) - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/FieldSolvers/Integrating/include) - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include) - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/include) - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/include) - - set (OPENCLPLUGIN_HEADERFILES - ${OPENCLPLUGIN_GENERATED_HEADER} - # - ${CMAKE_CURRENT_SOURCE_DIR}/Core/include/KOpenCLHeaderWrapper.hh - ${CMAKE_CURRENT_SOURCE_DIR}/Core/include/KOpenCLAction.hh - ${CMAKE_CURRENT_SOURCE_DIR}/Core/include/KOpenCLData.hh - ${CMAKE_CURRENT_SOURCE_DIR}/Core/include/KOpenCLInterface.hh - ${CMAKE_CURRENT_SOURCE_DIR}/Core/include/KOpenCLKernelBuilder.hh - # - ${CMAKE_CURRENT_SOURCE_DIR}/IO/include/KOpenCLBufferStreamer.hh - # - ${CMAKE_CURRENT_SOURCE_DIR}/Surfaces/include/KOpenCLSurfaceContainer.hh - # - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Core/include/KOpenCLBoundaryIntegrator.hh - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Core/include/KOpenCLBoundaryIntegralMatrix.hh - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Core/include/KOpenCLBoundaryIntegralVector.hh - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Core/include/KOpenCLBoundaryIntegralSolutionVector.hh - # - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/include/KOpenCLElectrostaticBoundaryIntegrator.hh - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/include/KOpenCLElectrostaticBoundaryIntegratorFactory.hh - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/include/KOpenCLElectrostaticNumericBoundaryIntegrator.hh - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/RWG/include/KOpenCLElectrostaticRWGBoundaryIntegrator.hh - # - ${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/include/KGaussSeidel_OpenCL.hh - #${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/include/KFMDenseBlockSparseMatrix_OpenCL.hh - # - ${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/include/KRobinHood_OpenCL.hh - # - ${CMAKE_CURRENT_SOURCE_DIR}/FieldSolvers/Integrating/include/KOpenCLElectrostaticIntegratingFieldSolver.hh - # - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticMultipoleBatchCalculator_OpenCL.hh - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticFastMultipoleFieldSolver_OpenCL.hh - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticFieldMapper_OpenCL.hh - #${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticBoundaryIntegratorEngine_OpenCL.hh - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticMultipoleCalculator_OpenCL.hh - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticRemoteToRemoteConverter_OpenCL.hh - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticRemoteToLocalConverter_OpenCL.hh - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticLocalToLocalConverter_OpenCL.hh - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticMultipoleDistributor_OpenCL.hh - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMSparseElectrostaticBoundaryIntegratorEngine_OpenCL.hh - #${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticSparseBoundaryIntegralShellMatrix_OpenCL.hh - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticBatchedRemoteToLocalConverter_OpenCL.hh - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticBatchedLocalToLocalConverter_OpenCL.hh - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticBatchedRemoteToRemoteConverter_OpenCL.hh - # - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/include/KFMBatchedMultidimensionalFastFourierTransform_OpenCL.hh - # - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/include/KFMScalarMomentRemoteToLocalConverter_OpenCL.hh - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/include/KFMReducedScalarMomentRemoteToLocalConverter_OpenCL.hh - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/include/KFMSparseReducedScalarMomentRemoteToLocalConverter_OpenCL.hh - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/include/KFMScalarMomentLocalToLocalConverter_OpenCL.hh - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/include/KFMScalarMomentRemoteToRemoteConverter_OpenCL.hh - ) - if (${PROJECT_NAME}_USE_MPI) - list (APPEND OPENCLPLUGIN_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/include/KRobinHood_MPI_OpenCL.hh - #${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticSparseBoundaryIntegralShellMatrix_MPI_OpenCL.hh - ) - endif (${PROJECT_NAME}_USE_MPI) - - set (OPENCLPLUGIN_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/Core/src/KOpenCLAction.cc - ${CMAKE_CURRENT_SOURCE_DIR}/Core/src/KOpenCLData.cc - ${CMAKE_CURRENT_SOURCE_DIR}/Core/src/KOpenCLInterface.cc - ${CMAKE_CURRENT_SOURCE_DIR}/Core/src/KOpenCLKernelBuilder.cc - # - ${CMAKE_CURRENT_SOURCE_DIR}/Surfaces/src/KOpenCLSurfaceContainer.cc - # - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/src/KOpenCLElectrostaticBoundaryIntegrator.cc - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/src/KOpenCLElectrostaticBoundaryIntegratorFactory.cc - #${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/src/KOpenCLElectrostaticNumericBoundaryIntegrator.cc - #${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/RWG/src/KOpenCLElectrostaticRWGBoundaryIntegrator.cc - # - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticMultipoleBatchCalculator_OpenCL.cc - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticFastMultipoleFieldSolver_OpenCL.cc - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticFieldMapper_OpenCL.cc - #${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticBoundaryIntegratorEngine_OpenCL.cc - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticMultipoleCalculator_OpenCL.cc - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticRemoteToRemoteConverter_OpenCL.cc - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticRemoteToLocalConverter_OpenCL.cc - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticBatchedRemoteToLocalConverter_OpenCL.cc - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticLocalToLocalConverter_OpenCL.cc - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticMultipoleDistributor_OpenCL.cc - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMSparseElectrostaticBoundaryIntegratorEngine_OpenCL.cc - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticBatchedRemoteToLocalConverter_OpenCL.cc - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticBatchedLocalToLocalConverter_OpenCL.cc - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticBatchedRemoteToRemoteConverter_OpenCL.cc +set(KEMField_OPENCL_PLATFORM "0" CACHE STRING "OpenCL platform ID number.") +mark_as_advanced(FORCE KEMField_OPENCL_PLATFORM) + +set(KEMField_OPENCL_DEVICE_TYPE "0" CACHE STRING "OpenCL device type; GPU=0, CPU=1, Accelerator=2; Any=-1.") +mark_as_advanced(FORCE KEMField_OPENCL_DEVICE_TYPE) + +set (KEMField_OPENCL_FASTDIELECTRICS "0" CACHE STRING + "Choose the check method of Neumann boundary elements in Robin Hood; 0 (check interval equal to Dirichlet elements), 1 (decrease checked accuracy of Neumann elements by 1/20), 2 (counter technique with the function RH_BoundaryRatioExceeded)") +mark_as_advanced(FORCE KEMField_OPENCL_FASTDIELECTRICS) + +cmake_dependent_option (KEMField_OPENCL_FASTRWG + "Activate the fast evaluation of electrostatic boundary integrals in RWG basis if no field point has to be computed on any surface." + OFF KEMField_USE_OPENCL OFF) +mark_as_advanced(FORCE KEMField_OPENCL_FASTRWG) + +cmake_dependent_option (KEMField_OPENCL_FFT_CONST_MEM "Enable use of OpenCL device constant memory by FFT kernel." ON KEMField_USE_OPENCL OFF) +mark_as_advanced(FORCE KEMField_OPENCL_FFT_CONST_MEM) +if (KEMField_OPENCL_FFT_CONST_MEM) + set (KEMField_OPENCL_CFLAGS ${KEMField_OPENCL_CFLAGS} -DKEMFIELD_OPENCL_FFT_CONST_MEM) +endif (KEMField_OPENCL_FFT_CONST_MEM) + +cmake_dependent_option (KEMField_OPENCL_USE_CL_VECTOR "Use deprecated cl::vector in place of std::vector" OFF KEMField_USE_OPENCL OFF) +mark_as_advanced(FORCE KEMField_OPENCL_USE_CL_VECTOR) +if (KEMField_OPENCL_USE_CL_VECTOR) + set (KEMField_OPENCL_CFLAGS ${KEMField_OPENCL_CFLAGS} -DKEMFIELD_USE_CL_VECTOR) +endif (KEMField_OPENCL_USE_CL_VECTOR) + +cmake_dependent_option (KEMField_OPENCL_INTERNAL_2_2 "Use internally packaged OpenCL 2.2 headers" OFF KEMField_USE_OPENCL OFF) +mark_as_advanced(FORCE KEMField_OPENCL_INTERNAL_2_2) +if (KEMField_OPENCL_INTERNAL_2_2) + set (KEMField_OPENCL_TEMP_INCLUDE_DIR_STR \"${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/opencl/2.2\") + string (REPLACE "\"" "" KEMField_OPENCL_TEMP_INCLUDE_DIR_VAR ${KEMField_OPENCL_TEMP_INCLUDE_DIR_STR} ) + set (KEMField_OPENCL_CFLAGS ${KEMField_OPENCL_CFLAGS} -isystem ${KEMField_OPENCL_TEMP_INCLUDE_DIR_VAR}) +endif (KEMField_OPENCL_INTERNAL_2_2) + +option (KEMField_USE_OPENCL "Use OpenCL via C++ wrapper API." OFF) +if (KEMField_USE_OPENCL) + + # force deactivation of FFTW because it permutes FFT outputs in a different way + # than the native FFT, which leads to incorrect fast multipole response functions + set( KEMField_USE_FFTW OFF CACHE BOOL "(Required)" FORCE) + + find_package (OpenCL REQUIRED) + + if(KEMField_OPENCL_INTERNAL_2_2) + set(OpenCL_INCLUDE_DIRS SYSTEM ${KEMField_OPENCL_TEMP_INCLUDE_DIR_STR}) + endif(KEMField_OPENCL_INTERNAL_2_2) + + message(STATUS "${PROJECT_NAME} is looking for compatbile OpenCL devices ...") + + if (APPLE) + execute_process(COMMAND ${CMAKE_CXX_COMPILER} + -D KEMFIELD_OPENCL_PLATFORM=${KEMField_OPENCL_PLATFORM} + -D KEMFIELD_OPENCL_DEVICE_TYPE=${KEMField_OPENCL_DEVICE_TYPE} + -o ${CMAKE_BINARY_DIR}/${PROJECT_NAME}/GenerateOpenCLHeader + -I${OpenCL_INCLUDE_DIRS} + ${KEMField_OPENCL_CFLAGS} + -framework OpenCL + ${SOURCE}/Plugins/OpenCL/Core/src/GenerateOpenCLHeader.cc + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + RESULT_VARIABLE COMPILE_STATUS + ) + else (APPLE) + execute_process(COMMAND ${CMAKE_CXX_COMPILER} + -D KEMFIELD_OPENCL_PLATFORM=${KEMField_OPENCL_PLATFORM} + -D KEMFIELD_OPENCL_DEVICE_TYPE=${KEMField_OPENCL_DEVICE_TYPE} + -o ${CMAKE_BINARY_DIR}/${PROJECT_NAME}/GenerateOpenCLHeader + -I${OpenCL_INCLUDE_DIRS} + ${KEMField_OPENCL_CFLAGS} + ${SOURCE}/Plugins/OpenCL/Core/src/GenerateOpenCLHeader.cc + ${OpenCL_LIBRARIES} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + RESULT_VARIABLE COMPILE_STATUS + ) + endif (APPLE) + + if(COMPILE_STATUS AND NOT COMPILE_STATUS EQUAL 0) + message(FATAL_ERROR " *** Could not build \"GenerateOpenCLHeader\" ***\n" + " There was an error compiling an OpenCL program. Please check your config.\n" + " KEMFIELD_OPENCL_PLATFORM=${KEMField_OPENCL_PLATFORM}\n" + " KEMFIELD_OPENCL_DEVICE_TYPE=${KEMField_OPENCL_DEVICE_TYPE}") + endif() + + set(OPENCLPLUGIN_GENERATED_HEADER ${CMAKE_BINARY_DIR}/${PROJECT_NAME}/kEMField_opencl_defines.h) + execute_process(COMMAND ${CMAKE_BINARY_DIR}/${PROJECT_NAME}/GenerateOpenCLHeader + OUTPUT_FILE ${OPENCLPLUGIN_GENERATED_HEADER} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + RESULT_VARIABLE EXEC_STATUS ) - set_property( - SOURCE - ${CMAKE_CURRENT_SOURCE_DIR}/Core/src/KOpenCLInterface.cc - APPEND PROPERTY COMPILE_DEFINITIONS DEFAULT_KERNEL_DIR="${${PROJECT_NAME}_DATA_INSTALL_DIR}" + if(EXEC_STATUS AND NOT EXEC_STATUS EQUAL 0) + file(REMOVE ${OPENCLPLUGIN_GENERATED_HEADER}) + message(FATAL_ERROR " *** Could not run \"GenerateOpenCLHeader\" ***\n" + " There was an error generating the OpenCL headers. Please check your config.\n" + " KEMFIELD_OPENCL_PLATFORM=${KEMField_OPENCL_PLATFORM}\n" + " KEMFIELD_OPENCL_DEVICE_TYPE=${KEMField_OPENCL_DEVICE_TYPE}") + else() + message(STATUS "OpenCL header was generated: ${OPENCLPLUGIN_GENERATED_HEADER}") + endif() + + #leave this binary around since it is useful for debugging if things go wrong + #execute_process(COMMAND rm GenerateOpenCLHeader WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + + set (OPENCLPLUGIN_HEADERFILES + ${OPENCLPLUGIN_GENERATED_HEADER} + + ${CMAKE_CURRENT_SOURCE_DIR}/Core/include/KOpenCLHeaderWrapper.hh + ${CMAKE_CURRENT_SOURCE_DIR}/Core/include/KOpenCLAction.hh + ${CMAKE_CURRENT_SOURCE_DIR}/Core/include/KOpenCLData.hh + ${CMAKE_CURRENT_SOURCE_DIR}/Core/include/KOpenCLInterface.hh + ${CMAKE_CURRENT_SOURCE_DIR}/Core/include/KOpenCLKernelBuilder.hh + + ${CMAKE_CURRENT_SOURCE_DIR}/IO/include/KOpenCLBufferStreamer.hh + + ${CMAKE_CURRENT_SOURCE_DIR}/Surfaces/include/KOpenCLSurfaceContainer.hh + + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Core/include/KOpenCLBoundaryIntegrator.hh + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Core/include/KOpenCLBoundaryIntegralMatrix.hh + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Core/include/KOpenCLBoundaryIntegralVector.hh + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Core/include/KOpenCLBoundaryIntegralSolutionVector.hh + + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/include/KOpenCLElectrostaticBoundaryIntegrator.hh + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/include/KOpenCLElectrostaticBoundaryIntegratorFactory.hh + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/include/KOpenCLElectrostaticNumericBoundaryIntegrator.hh + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/RWG/include/KOpenCLElectrostaticRWGBoundaryIntegrator.hh + + ${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/include/KGaussSeidel_OpenCL.hh + #${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/include/KFMDenseBlockSparseMatrix_OpenCL.hh + + ${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/include/KRobinHood_OpenCL.hh + + ${CMAKE_CURRENT_SOURCE_DIR}/FieldSolvers/Integrating/include/KOpenCLElectrostaticIntegratingFieldSolver.hh + + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticMultipoleBatchCalculator_OpenCL.hh + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticFastMultipoleFieldSolver_OpenCL.hh + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticFieldMapper_OpenCL.hh + #${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticBoundaryIntegratorEngine_OpenCL.hh + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticMultipoleCalculator_OpenCL.hh + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticRemoteToRemoteConverter_OpenCL.hh + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticRemoteToLocalConverter_OpenCL.hh + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticLocalToLocalConverter_OpenCL.hh + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticMultipoleDistributor_OpenCL.hh + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMSparseElectrostaticBoundaryIntegratorEngine_OpenCL.hh + #${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticSparseBoundaryIntegralShellMatrix_OpenCL.hh + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticBatchedRemoteToLocalConverter_OpenCL.hh + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticBatchedLocalToLocalConverter_OpenCL.hh + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticBatchedRemoteToRemoteConverter_OpenCL.hh + + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/include/KFMBatchedMultidimensionalFastFourierTransform_OpenCL.hh + + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/include/KFMScalarMomentRemoteToLocalConverter_OpenCL.hh + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/include/KFMReducedScalarMomentRemoteToLocalConverter_OpenCL.hh + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/include/KFMSparseReducedScalarMomentRemoteToLocalConverter_OpenCL.hh + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/include/KFMScalarMomentLocalToLocalConverter_OpenCL.hh + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/include/KFMScalarMomentRemoteToRemoteConverter_OpenCL.hh ) - set (OPENCLPLUGIN_CLFILES - ${OPENCLPLUGIN_GENERATED_HEADER} - # - ${CMAKE_CURRENT_SOURCE_DIR}/Math/cl/kEMField_GaussianQuadrature.cl - ${CMAKE_CURRENT_SOURCE_DIR}/Math/cl/kEMField_GaussianCubature.cl - ${CMAKE_CURRENT_SOURCE_DIR}/Math/cl/kEMField_VectorOperations.cl - # - ${CMAKE_CURRENT_SOURCE_DIR}/Core/cl/kEMField_ParallelReduction.cl - # - ${CMAKE_CURRENT_SOURCE_DIR}/Surfaces/cl/kEMField_Rectangle.cl - ${CMAKE_CURRENT_SOURCE_DIR}/Surfaces/cl/kEMField_Triangle.cl - ${CMAKE_CURRENT_SOURCE_DIR}/Surfaces/cl/kEMField_LineSegment.cl - ${CMAKE_CURRENT_SOURCE_DIR}/Surfaces/cl/kEMField_ConicSection.cl - ${CMAKE_CURRENT_SOURCE_DIR}/Surfaces/cl/kEMField_SolidAngle.cl - # - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Core/cl/kEMField_BoundaryIntegrals.cl - # - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/cl/kEMField_ElectrostaticRectangle.cl - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/cl/kEMField_ElectrostaticTriangle.cl - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/cl/kEMField_ElectrostaticLineSegment.cl - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/cl/kEMField_ElectrostaticConicSection.cl - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/cl/kEMField_ElectrostaticBoundaryIntegrals.cl - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/cl/kEMField_ElectrostaticBoundaryIntegrals_kernel.cl - # - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticCubature_CommonFunctions.cl - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticCubatureTriangle_7Point.cl - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticCubatureTriangle_12Point.cl - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticCubatureTriangle_33Point.cl - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticCubatureRectangle_7Point.cl - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticCubatureRectangle_12Point.cl - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticCubatureRectangle_33Point.cl - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticQuadratureLineSegment.cl - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticNumericBoundaryIntegrals.cl - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticNumericBoundaryIntegrals_kernel.cl - # - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/RWG/cl/kEMField_ElectrostaticRWGBoundaryIntegrals.cl - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/RWG/cl/kEMField_ElectrostaticRWGBoundaryIntegrals_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/RWG/cl/kEMField_ElectrostaticRWGRectangle.cl - ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/RWG/cl/kEMField_ElectrostaticRWGTriangle.cl - # - ${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/cl/kEMField_LinearAlgebra.cl - ${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/cl/kEMField_LinearAlgebra_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/cl/kEMField_GaussSeidel_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/cl/kEMField_RobinHood_kernel.cl - #${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/cl/kEMField_DenseBlockSparseMatrixVectorProduct_kernel.cl - # - ${CMAKE_CURRENT_SOURCE_DIR}/FieldSolvers/Integrating/cl/kEMField_ElectrostaticIntegratingFieldSolver_kernel.cl - # - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMSphericalMultipoleMath.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMMultipoleRotation.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMMultipoleTranslation.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMRotationMatrix.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMArrayMath.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMZeroComplexArray_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMFastFourierTransformUtilities.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMMultidimensionalFastFourierTransform_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMFastFourierTransformUtilitiesPrivate.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMMultidimensionalFastFourierTransformPrivate_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMFastFourierTransformUtilitiesLocal.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMMultidimensionalFastFourierTransformLocal_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMPointwiseComplexVectorAdd_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMComplexMultiply.cl - # - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticMultipole_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticMultipoleDistribution_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMTriangleMultipole.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMTriangleMultipoleNumerical.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMRectangleMultipole.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMRectangleMultipoleNumerical.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMLineSegmentMultipole.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMLineSegmentMultipoleNumerical.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticRemoteToRemoteCopyAndScale_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticRemoteToRemoteReduceAndScale_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticRemoteToRemoteTransformation_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticRemoteToLocalCopyAndScale_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticRemoteToLocalReduceAndScale_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticLocalToLocalTransformation_kernel.cl - #${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticSparseShellMatrixVectorProduct_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticBufferedRemoteToLocalCopyAndScale_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticBufferedRemoteToLocalReduceAndScale_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticBatchedLocalToLocalTransformation_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticBatchedRemoteToRemoteReduce_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticBatchedRemoteToRemoteTransformation_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticBatchedRemoteToLocalTransformation_kernel.cl - # - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/cl/kEMField_KFMScalarMomentRemoteToRemoteConverter_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/cl/kEMField_KFMScalarMomentRemoteToLocalConverter_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/cl/kEMField_KFMReducedScalarMomentRemoteToLocalConverter_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/cl/kEMField_KFMBufferedReducedScalarMomentRemoteToLocalConverter_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/cl/kEMField_KFMSparseScalarMomentAdd_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/cl/kEMField_KFMScalarMomentLocalToLocalConverter_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/cl/kEMField_KFMScalarMomentApplyScaleFactor_kernel.cl - ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/cl/kEMField_KFMScalarMomentArrayReduction_kernel.cl + if (KEMField_USE_MPI) + list (APPEND OPENCLPLUGIN_HEADERFILES + ${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/include/KRobinHood_MPI_OpenCL.hh + #${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/include/KFMElectrostaticSparseBoundaryIntegralShellMatrix_MPI_OpenCL.hh + ) + endif (KEMField_USE_MPI) + + set (OPENCLPLUGIN_SOURCEFILES + ${CMAKE_CURRENT_SOURCE_DIR}/Core/src/KOpenCLAction.cc + ${CMAKE_CURRENT_SOURCE_DIR}/Core/src/KOpenCLData.cc + ${CMAKE_CURRENT_SOURCE_DIR}/Core/src/KOpenCLInterface.cc + ${CMAKE_CURRENT_SOURCE_DIR}/Core/src/KOpenCLKernelBuilder.cc + + ${CMAKE_CURRENT_SOURCE_DIR}/Surfaces/src/KOpenCLSurfaceContainer.cc + + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/src/KOpenCLElectrostaticBoundaryIntegrator.cc + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/src/KOpenCLElectrostaticBoundaryIntegratorFactory.cc + #${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/src/KOpenCLElectrostaticNumericBoundaryIntegrator.cc + #${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/RWG/src/KOpenCLElectrostaticRWGBoundaryIntegrator.cc + + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticMultipoleBatchCalculator_OpenCL.cc + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticFastMultipoleFieldSolver_OpenCL.cc + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticFieldMapper_OpenCL.cc + #${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticBoundaryIntegratorEngine_OpenCL.cc + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticMultipoleCalculator_OpenCL.cc + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticRemoteToRemoteConverter_OpenCL.cc + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticRemoteToLocalConverter_OpenCL.cc + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticBatchedRemoteToLocalConverter_OpenCL.cc + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticLocalToLocalConverter_OpenCL.cc + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticMultipoleDistributor_OpenCL.cc + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMSparseElectrostaticBoundaryIntegratorEngine_OpenCL.cc + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticBatchedRemoteToLocalConverter_OpenCL.cc + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticBatchedLocalToLocalConverter_OpenCL.cc + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/src/KFMElectrostaticBatchedRemoteToRemoteConverter_OpenCL.cc ) - add_library (KEMOpenCLPlugin SHARED ${OPENCLPLUGIN_SOURCEFILES} ${OPENCLPLUGIN_HEADERFILES}) - target_link_libraries (KEMOpenCLPlugin - KEMCore - KEMSurfaces - KFMKernel - KFMTree - KFMMath - KFMMathUtilities - KFMElectrostatics - ${OpenCL_LIBRARIES} + set_property(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/Core/src/KOpenCLInterface.cc + APPEND PROPERTY COMPILE_DEFINITIONS DEFAULT_KERNEL_DIR="${KEMField_DATA_INSTALL_DIR}") + + set (OPENCLPLUGIN_CLFILES + ${OPENCLPLUGIN_GENERATED_HEADER} + + ${CMAKE_CURRENT_SOURCE_DIR}/Math/cl/kEMField_GaussianQuadrature.cl + ${CMAKE_CURRENT_SOURCE_DIR}/Math/cl/kEMField_GaussianCubature.cl + ${CMAKE_CURRENT_SOURCE_DIR}/Math/cl/kEMField_VectorOperations.cl + + ${CMAKE_CURRENT_SOURCE_DIR}/Core/cl/kEMField_ParallelReduction.cl + + ${CMAKE_CURRENT_SOURCE_DIR}/Surfaces/cl/kEMField_Rectangle.cl + ${CMAKE_CURRENT_SOURCE_DIR}/Surfaces/cl/kEMField_Triangle.cl + ${CMAKE_CURRENT_SOURCE_DIR}/Surfaces/cl/kEMField_LineSegment.cl + ${CMAKE_CURRENT_SOURCE_DIR}/Surfaces/cl/kEMField_ConicSection.cl + ${CMAKE_CURRENT_SOURCE_DIR}/Surfaces/cl/kEMField_SolidAngle.cl + + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Core/cl/kEMField_BoundaryIntegrals.cl + + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/cl/kEMField_ElectrostaticRectangle.cl + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/cl/kEMField_ElectrostaticTriangle.cl + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/cl/kEMField_ElectrostaticLineSegment.cl + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/cl/kEMField_ElectrostaticConicSection.cl + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/cl/kEMField_ElectrostaticBoundaryIntegrals.cl + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/Electrostatic/cl/kEMField_ElectrostaticBoundaryIntegrals_kernel.cl + + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticCubature_CommonFunctions.cl + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticCubatureTriangle_7Point.cl + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticCubatureTriangle_12Point.cl + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticCubatureTriangle_33Point.cl + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticCubatureRectangle_7Point.cl + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticCubatureRectangle_12Point.cl + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticCubatureRectangle_33Point.cl + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticQuadratureLineSegment.cl + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticNumericBoundaryIntegrals.cl + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/ElectrostaticNumeric/cl/kEMField_ElectrostaticNumericBoundaryIntegrals_kernel.cl + + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/RWG/cl/kEMField_ElectrostaticRWGBoundaryIntegrals.cl + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/RWG/cl/kEMField_ElectrostaticRWGBoundaryIntegrals_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/RWG/cl/kEMField_ElectrostaticRWGRectangle.cl + ${CMAKE_CURRENT_SOURCE_DIR}/BoundaryIntegrals/RWG/cl/kEMField_ElectrostaticRWGTriangle.cl + + ${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/cl/kEMField_LinearAlgebra.cl + ${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/cl/kEMField_LinearAlgebra_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/cl/kEMField_GaussSeidel_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/cl/kEMField_RobinHood_kernel.cl + #${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/cl/kEMField_DenseBlockSparseMatrixVectorProduct_kernel.cl + + ${CMAKE_CURRENT_SOURCE_DIR}/FieldSolvers/Integrating/cl/kEMField_ElectrostaticIntegratingFieldSolver_kernel.cl + + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMSphericalMultipoleMath.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMMultipoleRotation.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMMultipoleTranslation.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMRotationMatrix.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMArrayMath.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMZeroComplexArray_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMFastFourierTransformUtilities.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMMultidimensionalFastFourierTransform_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMFastFourierTransformUtilitiesPrivate.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMMultidimensionalFastFourierTransformPrivate_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMFastFourierTransformUtilitiesLocal.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMMultidimensionalFastFourierTransformLocal_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMPointwiseComplexVectorAdd_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Math/cl/kEMField_KFMComplexMultiply.cl + + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticMultipole_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticMultipoleDistribution_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMTriangleMultipole.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMTriangleMultipoleNumerical.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMRectangleMultipole.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMRectangleMultipoleNumerical.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMLineSegmentMultipole.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMLineSegmentMultipoleNumerical.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticRemoteToRemoteCopyAndScale_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticRemoteToRemoteReduceAndScale_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticRemoteToRemoteTransformation_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticRemoteToLocalCopyAndScale_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticRemoteToLocalReduceAndScale_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticLocalToLocalTransformation_kernel.cl + #${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticSparseShellMatrixVectorProduct_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticBufferedRemoteToLocalCopyAndScale_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticBufferedRemoteToLocalReduceAndScale_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticBatchedLocalToLocalTransformation_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticBatchedRemoteToRemoteReduce_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticBatchedRemoteToRemoteTransformation_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Electrostatics/cl/kEMField_KFMElectrostaticBatchedRemoteToLocalTransformation_kernel.cl + + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/cl/kEMField_KFMScalarMomentRemoteToRemoteConverter_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/cl/kEMField_KFMScalarMomentRemoteToLocalConverter_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/cl/kEMField_KFMReducedScalarMomentRemoteToLocalConverter_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/cl/kEMField_KFMBufferedReducedScalarMomentRemoteToLocalConverter_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/cl/kEMField_KFMSparseScalarMomentAdd_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/cl/kEMField_KFMScalarMomentLocalToLocalConverter_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/cl/kEMField_KFMScalarMomentApplyScaleFactor_kernel.cl + ${CMAKE_CURRENT_SOURCE_DIR}/FastMultipole/Tree/cl/kEMField_KFMScalarMomentArrayReduction_kernel.cl ) - kasper_install_headers (${OPENCLPLUGIN_HEADERFILES}) - kasper_install_libraries (KEMOpenCLPlugin) - - # Generate GPU-specific headers for OpenCL implementation of KEMField + add_library (KEMOpenCLPlugin SHARED + ${OPENCLPLUGIN_SOURCEFILES} ${OPENCLPLUGIN_HEADERFILES}) + + # get header paths from collected header files + foreach(HEADER ${OPENCLPLUGIN_HEADERFILES}) + get_filename_component(DIRNAME ${HEADER} DIRECTORY) + target_include_directories(KEMOpenCLPlugin PUBLIC $) + endforeach(HEADER) + target_include_directories(KEMOpenCLPlugin PUBLIC $) + + target_compile_definitions(KEMOpenCLPlugin + PUBLIC + KEMFIELD_USE_OPENCL + KEMFIELD_OPENCL_PLATFORM=${KEMField_OPENCL_PLATFORM} + KEMFIELD_OPENCL_DEVICE_TYPE=${KEMField_OPENCL_DEVICE_TYPE} + ) - install ( FILES ${OPENCLPLUGIN_CLFILES} - DESTINATION ${${PROJECT_NAME}_DATA_INSTALL_DIR} + target_link_libraries (KEMOpenCLPlugin + PUBLIC + KEMCore + KEMSurfaces + KEMElectrostaticBoundaryIntegrals + KEMIntegratingSolver + KFMElectrostatics + OpenCL::OpenCL ) -endif (${PROJECT_NAME}_USE_OPENCL) + if(KEMField_OPENCL_FASTRWG) + target_compile_definitions(KEMOpenCLPlugin PRIVATE KEMFIELD_FASTRWG_VALUE=1) + else(KEMField_OPENCL_FASTRWG) + target_compile_definitions(KEMOpenCLPlugin PRIVATE KEMFIELD_FASTRWG_VALUE=0) + endif(KEMField_OPENCL_FASTRWG) + if(KEMField_OPENCL_FFT_CONST_MEM) + target_compile_definitions(KEMOpenCLPlugin PRIVATE KEMFIELD_OPENCL_FFT_CONST_MEM) + endif(KEMField_OPENCL_FFT_CONST_MEM) + if(KEMField_OPENCL_USE_CL_VECTOR) + target_compile_definitions(KEMOpenCLPlugin PRIVATE KEMFIELD_USE_CL_VECTOR) + endif(KEMField_OPENCL_USE_CL_VECTOR) + + if( CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_COMPILER_IS_GNUCXX ) + if( NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "7.0" ) + # Use -faligned-new flag to trick gcc into using aligned allocators CL types. + # This is only used by KEMField, but required here because of include files. + target_compile_options(KEMOpenCLPlugin PUBLIC $<$:-faligned-new> ) + endif() + endif() + + kasper_install_headers (${OPENCLPLUGIN_HEADERFILES}) + kasper_install_libraries (KEMOpenCLPlugin) + + # Generate GPU-specific headers for OpenCL implementation of KEMField + + install ( FILES ${OPENCLPLUGIN_CLFILES} DESTINATION ${KEMField_DATA_INSTALL_DIR} ) + +endif (KEMField_USE_OPENCL) diff --git a/KEMField/Source/Plugins/PETSc/CMakeLists.txt b/KEMField/Source/Plugins/PETSc/CMakeLists.txt index 232174482..8056f744b 100644 --- a/KEMField/Source/Plugins/PETSc/CMakeLists.txt +++ b/KEMField/Source/Plugins/PETSc/CMakeLists.txt @@ -1,37 +1,35 @@ # CMakeLists for KEMField/Plugins/PETSc # T.J. Corona -cmake_dependent_option (${PROJECT_NAME}_USE_PETSc "Use PETSc for charge density computation" OFF ${PROJECT_NAME}_USE_MPI OFF) +cmake_dependent_option (KEMField_USE_PETSc "Use PETSc for charge density computation" OFF KEMField_USE_MPI OFF) +if (KEMField_USE_PETSc) -if (NOT ${PROJECT_NAME}_USE_MPI) - set (${PROJECT_NAME}_USE_PETSc OFF) - set (${PROJECT_NAME}_USE_PETSc ${${PROJECT_NAME}_USE_PETSc} PARENT_SCOPE) -endif (NOT ${PROJECT_NAME}_USE_MPI) + find_package (PETSc REQUIRED) -if (${PROJECT_NAME}_USE_PETSc) - - find_package (PETSc REQUIRED) - kasper_external_include_directories (${PETSC_INCLUDES}) - add_cflag (KEMFIELD_USE_PETSC) - - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - - set (PETSCPLUGIN_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KPETScInterface.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KPETScSolver.hh + set (PETSCPLUGIN_HEADERFILES + ${CMAKE_CURRENT_SOURCE_DIR}/include/KPETScInterface.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KPETScSolver.hh ) - set (PETSCPLUGIN_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/src/KPETScInterface.cc + set (PETSCPLUGIN_SOURCEFILES + ${CMAKE_CURRENT_SOURCE_DIR}/src/KPETScInterface.cc ) - add_library (KEMPETScPlugin SHARED ${PETSCPLUGIN_SOURCEFILES} ${PETSCPLUGIN_HEADERFILES}) - target_link_libraries (KEMPETScPlugin - KEMCore - KEMSurfaces - ${PETSC_LIBRARY}) + add_library (KEMPETScPlugin SHARED + ${PETSCPLUGIN_SOURCEFILES} ${PETSCPLUGIN_HEADERFILES}) + target_include_directories(KEMPETScPlugin + PUBLIC $ $) + target_include_directories(KEMPETScPlugin PUBLIC ${PETSC_INCLUDES}) + + target_compile_definitions(KEMPETScPlugin PUBLIC KEMFIELD_USE_PETSC) + target_link_libraries (KEMPETScPlugin + PUBLIC + KEMSurfaces + PRIVATE + ${PETSC_LIBRARY} + ) - kasper_install_headers (${PETSCPLUGIN_HEADERFILES}) - kasper_install_libraries (KEMPETScPlugin) + kasper_install_headers (${PETSCPLUGIN_HEADERFILES}) + kasper_install_libraries (KEMPETScPlugin) -endif (${PROJECT_NAME}_USE_PETSc) +endif (KEMField_USE_PETSc) diff --git a/KEMField/Source/Plugins/Root/CMakeLists.txt b/KEMField/Source/Plugins/Root/CMakeLists.txt index 40c9d4563..56b9cc251 100644 --- a/KEMField/Source/Plugins/Root/CMakeLists.txt +++ b/KEMField/Source/Plugins/Root/CMakeLists.txt @@ -1,29 +1,35 @@ # CMakeLists for KEMField/Plugins/Root # Author: T.J. Corona -if (${PROJECT_NAME}_USE_ROOT) - kasper_external_include_directories (${ROOT_INCLUDE_DIRS}) - add_cflag (KEMFIELD_USE_ROOT) +if (KEMField_USE_ROOT) - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) + set (KEMROOT_HEADERFILES + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMElectricFieldPointsRootFile.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMRootFieldCanvas.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMRootSVDSolver.hh + ) - set (KEMROOT_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMElectricFieldPointsRootFile.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMRootFieldCanvas.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMRootSVDSolver.hh - ) + set (KEMROOT_SOURCEFILES + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMElectricFieldPointsRootFile.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMRootFieldCanvas.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMRootSVDSolver.cc + ) - set (KEMROOT_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMElectricFieldPointsRootFile.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMRootFieldCanvas.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMRootSVDSolver.cc - ) + add_library (KEMRootPlugin SHARED + ${KEMROOT_SOURCEFILES} ${KEMROOT_HEADERFILES}) + target_include_directories(KEMRootPlugin + PUBLIC $ $) + target_link_libraries (KEMRootPlugin + PUBLIC + KEMVisualization + KEMMath + KEMLinearAlgebraCore + ROOT::Core + ROOT::Tree + ROOT::Physics + ) - add_library (KEMRootPlugin SHARED ${KEMROOT_SOURCEFILES} ${KEMROOT_HEADERFILES}) - target_link_libraries (KEMRootPlugin KEMVisualization - KEMMath KEMCore ${Kommon_LIBRARIES} ${KGeoBag_LIBRARIES} ${GSL_LIBRARIES} ${ROOT_LIBRARIES} ) + kasper_install_headers (${KEMROOT_HEADERFILES}) + kasper_install_libraries (KEMRootPlugin) - kasper_install_headers (${KEMROOT_HEADERFILES}) - kasper_install_libraries (KEMRootPlugin) - -endif (${PROJECT_NAME}_USE_ROOT) +endif (KEMField_USE_ROOT) diff --git a/KEMField/Source/Plugins/VTK/CMakeLists.txt b/KEMField/Source/Plugins/VTK/CMakeLists.txt index c921b4e5b..3bb5a562a 100644 --- a/KEMField/Source/Plugins/VTK/CMakeLists.txt +++ b/KEMField/Source/Plugins/VTK/CMakeLists.txt @@ -1,53 +1,52 @@ # CMakeLists for KEMField/Plugins/VTK # Author: T.J. Corona -if (${PROJECT_NAME}_USE_VTK) - add_cflag (KEMFIELD_USE_VTK) - - kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - - set (VTKPLUGIN_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMVTKViewer.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMVTKElectromagnetViewer.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMVTKFieldCanvas.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KVTKIterationPlotter.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KVTKResidualGraph.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMVTKElectrostaticTreeViewer.hh +if (KEMField_USE_VTK) + + set (VTKPLUGIN_HEADERFILES + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMVTKViewer.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMVTKElectromagnetViewer.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMVTKFieldCanvas.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KVTKIterationPlotter.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KVTKResidualGraph.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KFMVTKElectrostaticTreeViewer.hh ) - set (VTKPLUGIN_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMVTKViewer.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMVTKElectromagnetViewer.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMVTKFieldCanvas.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KFMVTKElectrostaticTreeViewer.cc + set (VTKPLUGIN_SOURCEFILES + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMVTKViewer.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMVTKElectromagnetViewer.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMVTKFieldCanvas.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KFMVTKElectrostaticTreeViewer.cc ) - if (VTK_MAJOR_VERSION GREATER 5) - set_property( - SOURCE - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMVTKViewer.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMVTKFieldCanvas.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KFMVTKElectrostaticTreeViewer.cc - APPEND PROPERTY COMPILE_DEFINITIONS VTK6 - ) - endif () - - set( VTKPLUGIN_LINK_LIBRARIES - KEMSurfaces - KEMVisualization - KFMCore - KFMElectrostatics - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - ${GSL_LIBRARIES} - ${OPENCL_LIBRARIES} - ${VTK_LIBRARIES} - ) - - add_library (KEMVTKPlugin SHARED ${VTKPLUGIN_SOURCEFILES} ${VTKPLUGIN_HEADERFILES}) - target_link_libraries (KEMVTKPlugin ${VTKPLUGIN_LINK_LIBRARIES}) - - kasper_install_headers (${VTKPLUGIN_HEADERFILES}) - kasper_install_libraries (KEMVTKPlugin) - -endif (${PROJECT_NAME}_USE_VTK) + if (VTK_MAJOR_VERSION GREATER 5) + set_property( + SOURCE + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMVTKViewer.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMVTKFieldCanvas.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KFMVTKElectrostaticTreeViewer.cc + APPEND PROPERTY COMPILE_DEFINITIONS VTK6 + ) + endif () + + + add_library (KEMVTKPlugin SHARED + ${VTKPLUGIN_SOURCEFILES} ${VTKPLUGIN_HEADERFILES}) + target_include_directories(KEMVTKPlugin + PUBLIC $ $) + target_link_libraries (KEMVTKPlugin + PUBLIC + KEMSurfaces + KEMElectromagnets + KEMVisualization + KFMElectrostatics + KEMLinearAlgebraSolvers + KommonVtk + ) + + target_compile_definitions(KEMVTKPlugin PUBLIC KEMFIELD_USE_VTK ) + + kasper_install_headers (${VTKPLUGIN_HEADERFILES}) + kasper_install_libraries (KEMVTKPlugin) + +endif (KEMField_USE_VTK) diff --git a/KEMField/Source/Plugins/VTK/include/KVTKIterationPlotter.hh b/KEMField/Source/Plugins/VTK/include/KVTKIterationPlotter.hh index 02b768696..ad096e8ec 100644 --- a/KEMField/Source/Plugins/VTK/include/KVTKIterationPlotter.hh +++ b/KEMField/Source/Plugins/VTK/include/KVTKIterationPlotter.hh @@ -55,6 +55,8 @@ template void KVTKIterationPlotter::InitializePlo // Set up the view fView = vtkSmartPointer::New(); fView->GetRenderer()->SetBackground(1.0, 1.0, 1.0); + fView->GetRenderWindow()->SetSize(500, 300); + fView->GetRenderWindow()->SetMultiSamples(0); // Add line plot, setting the colors etc fChart = vtkSmartPointer::New(); @@ -64,6 +66,7 @@ template void KVTKIterationPlotter::InitializePlo // fView->GetRenderWindow()->SetPosition(2810,2000); fView->GetScene()->AddItem(fChart); + fView->GetInteractor()->Initialize(); } template void KVTKIterationPlotter::CreatePlot() @@ -72,14 +75,24 @@ template void KVTKIterationPlotter::CreatePlot() table->AddColumn(fArrayX); table->AddColumn(fArrayY); - vtkPlot* line = fChart->AddPlot(vtkChart::LINE); + vtkPlot* dots = fChart->AddPlot(vtkChart::POINTS); #if VTK_MAJOR_VERSION <= 5 - line->SetInput(table, 0, 1); + dots->SetInput(table, 0, 1); #else - line->SetInputData(table, 0, 1); + dots->SetInputData(table, 0, 1); #endif - line->SetColor(0, 255, 0, 255); - line->SetWidth(1.0); + dots->SetColor(0, 0, 0, 255); + + if (fArrayX->GetSize() >= 2) { + vtkPlot* line = fChart->AddPlot(vtkChart::LINE); +#if VTK_MAJOR_VERSION <= 5 + line->SetInput(table, 0, 1); +#else + line->SetInputData(table, 0, 1); +#endif + line->SetColor(0, 0, 255, 255); + line->SetWidth(1.0); + } fChart->Modified(); fView->GetRenderWindow()->Render(); @@ -87,10 +100,10 @@ template void KVTKIterationPlotter::CreatePlot() template void KVTKIterationPlotter::AddPoint(float x, float y) { + std::cout << "adding points: " << x << ", " << y << std::endl; fArrayX->InsertNextValue(x); fArrayY->InsertNextValue(y); - if (fArrayX->GetSize() > 2) - CreatePlot(); + CreatePlot(); } template void KVTKIterationPlotter::Initialize(KIterativeSolver&) @@ -105,6 +118,8 @@ template void KVTKIterationPlotter::Visit(KIterat template void KVTKIterationPlotter::Finalize(KIterativeSolver&) { + kem_cout() << "KVTKIterationPlotter finished; waiting for key press ..." << eom; + fView->GetInteractor()->Start(); fView->GetRenderWindow()->Finalize(); } } // namespace KEMField diff --git a/KEMField/Source/Plugins/VTK/include/KVTKResidualGraph.hh b/KEMField/Source/Plugins/VTK/include/KVTKResidualGraph.hh index 5465c16ff..14b8dae21 100644 --- a/KEMField/Source/Plugins/VTK/include/KVTKResidualGraph.hh +++ b/KEMField/Source/Plugins/VTK/include/KVTKResidualGraph.hh @@ -65,6 +65,8 @@ template void KVTKResidualGraph::InitializeGraph( // Set up the view fView = vtkSmartPointer::New(); fView->GetRenderer()->SetBackground(1.0, 1.0, 1.0); + fView->GetRenderWindow()->SetSize(500, 300); + fView->GetRenderWindow()->SetMultiSamples(0); // Add line plot, setting the colors etc fChart = vtkSmartPointer::New(); @@ -75,8 +77,8 @@ template void KVTKResidualGraph::InitializeGraph( fChart->GetAxis(vtkAxis::BOTTOM)->SetTitle("Dimension"); // fView->GetRenderWindow()->SetPosition(2810,2000); - fView->GetRenderWindow()->SetSize(1000, 256); fView->GetScene()->AddItem(fChart); + fView->GetInteractor()->Initialize(); } template void KVTKResidualGraph::CreateGraph() @@ -121,6 +123,8 @@ template void KVTKResidualGraph::Visit(KIterative template void KVTKResidualGraph::Finalize(KIterativeSolver&) { + kem_cout() << "KVTKResidualGraph finished; waiting for key press ..." << eom; + fView->GetInteractor()->Start(); fView->GetRenderWindow()->Finalize(); } } // namespace KEMField diff --git a/KEMField/Source/Plugins/VTK/src/KEMVTKViewer.cc b/KEMField/Source/Plugins/VTK/src/KEMVTKViewer.cc index e8b35909b..b8790ad03 100644 --- a/KEMField/Source/Plugins/VTK/src/KEMVTKViewer.cc +++ b/KEMField/Source/Plugins/VTK/src/KEMVTKViewer.cc @@ -41,6 +41,8 @@ KEMVTKViewer::KEMVTKViewer(KSurfaceContainer& aSurfaceContainer) fArcPolyApprox = 128; for (KSurfaceContainer::iterator it = aSurfaceContainer.begin(); it != aSurfaceContainer.end(); it++) { + if (! *it) + continue; SetSurfacePrimitive(*it); ActOnSurfaceType((*it)->GetID(), *this); } diff --git a/KEMField/Source/Plugins/VTKPart2/CMakeLists.txt b/KEMField/Source/Plugins/VTKPart2/CMakeLists.txt index 06b20f36e..46f4b5b58 100644 --- a/KEMField/Source/Plugins/VTKPart2/CMakeLists.txt +++ b/KEMField/Source/Plugins/VTKPart2/CMakeLists.txt @@ -1,66 +1,55 @@ # CMakeLists for KEMField/Plugins/VTKPart2 # Author: W. Gosda -# This library is the second part of the vtk plugin. This split is necessary to avoid -#circular dependencies. +# This library is the second part of the vtk plugin. This split is necessary to +# avoid circular dependencies. # The library is build even with VTK disabled to provide a function less empty # version of the KVTKViewerAsBoundaryFieldVisitor to avoid parser errors. -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - #header files set( VTK-PART2_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KVTKViewerAsBoundaryFieldVisitor.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KVTKViewerAsBoundaryFieldVisitor.hh ) -if( ${PROJECT_NAME}_USE_VTK ) +if( KEMField_USE_VTK ) list( APPEND VTK-PART2_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectrostaticPotentialmap.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KMagnetostaticFieldmap.hh ) -endif( ${PROJECT_NAME}_USE_VTK ) +endif( KEMField_USE_VTK ) #source files set( VTK-PART2_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/src/KVTKViewerAsBoundaryFieldVisitor.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KVTKViewerAsBoundaryFieldVisitor.cc ) -if( ${PROJECT_NAME}_USE_VTK ) +if( KEMField_USE_VTK ) list( APPEND VTK-PART2_SOURCEFILES ${CMAKE_CURRENT_SOURCE_DIR}/src/KElectrostaticPotentialmap.cc ${CMAKE_CURRENT_SOURCE_DIR}/src/KMagnetostaticFieldmap.cc ) -endif( ${PROJECT_NAME}_USE_VTK ) +endif( KEMField_USE_VTK ) #link libraries -set( VTK-PART2_LINK_LIBRARIES - KEMFieldsElectric - KEMFieldsMagnetic -) -if( ${PROJECT_NAME}_USE_VTK ) - list( APPEND VTK-PART2_LINK_LIBRARIES - KEMVTKPlugin - - ) -endif( ${PROJECT_NAME}_USE_VTK ) - -if( ${PROJECT_NAME}_USE_VTK ) - list( APPEND VTK-PART2_LINK_LIBRARIES - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - ${VTK_LIBRARIES} - - ) -endif( ${PROJECT_NAME}_USE_VTK ) - add_library (KEMVTKPart2 SHARED - ${VTK-PART2_SOURCEFILES} + ${VTK-PART2_SOURCEFILES} ${VTK-PART2_HEADERFILES}) +target_include_directories(KEMVTKPart2 + PUBLIC $ $) +target_link_libraries (KEMVTKPart2 + PUBLIC + KEMFieldsElectric + KEMFieldsMagnetic ) -target_link_libraries ( KEMVTKPart2 ${VTK-PART2_LINK_LIBRARIES}) +if( KEMField_USE_VTK ) + target_link_libraries(KEMVTKPart2 + PUBLIC + KEMVTKPlugin + ) +endif( KEMField_USE_VTK ) kasper_install_headers ( ${VTK-PART2_HEADERFILES} ) kasper_install_libraries (KEMVTKPart2) diff --git a/KEMField/Source/Plugins/VTKPart2/include/KVTKViewerAsBoundaryFieldVisitor.hh b/KEMField/Source/Plugins/VTKPart2/include/KVTKViewerAsBoundaryFieldVisitor.hh index 1d55a56ff..14338898c 100644 --- a/KEMField/Source/Plugins/VTKPart2/include/KVTKViewerAsBoundaryFieldVisitor.hh +++ b/KEMField/Source/Plugins/VTKPart2/include/KVTKViewerAsBoundaryFieldVisitor.hh @@ -35,6 +35,11 @@ class KVTKViewerAsBoundaryFieldVisitor : public KElectrostaticBoundaryField::Vis fFile = file; } + void SetPath(const std::string& path) + { + fPath = path; + } + bool ViewGeometry() const { return fViewGeometry; @@ -52,6 +57,7 @@ class KVTKViewerAsBoundaryFieldVisitor : public KElectrostaticBoundaryField::Vis bool fViewGeometry; bool fSaveGeometry; std::string fFile; + std::string fPath; }; } /* namespace KEMField */ diff --git a/KEMField/Source/Plugins/VTKPart2/src/KElectrostaticPotentialmap.cc b/KEMField/Source/Plugins/VTKPart2/src/KElectrostaticPotentialmap.cc index 47c972058..b8f0f383d 100644 --- a/KEMField/Source/Plugins/VTKPart2/src/KElectrostaticPotentialmap.cc +++ b/KEMField/Source/Plugins/VTKPart2/src/KElectrostaticPotentialmap.cc @@ -623,7 +623,6 @@ void KElectrostaticPotentialmapCalculator::Execute() bool tHasValue = false; KFieldVector tField; - if (fMirrorX || fMirrorY || fMirrorZ) { double tMirrorPoint[3]; tMirrorPoint[0] = tPoint[0]; @@ -643,6 +642,13 @@ void KElectrostaticPotentialmapCalculator::Execute() { tField.SetComponents(fFieldData->GetTuple3(j)); tHasValue = true; + + if (tMirrorPoint[0] != tPoint[0]) + tField[0] *= -1; + if (tMirrorPoint[1] != tPoint[1]) + tField[1] *= -1; + if (tMirrorPoint[2] != tPoint[2]) + tField[2] *= -1; } } } diff --git a/KEMField/Source/Plugins/VTKPart2/src/KMagnetostaticFieldmap.cc b/KEMField/Source/Plugins/VTKPart2/src/KMagnetostaticFieldmap.cc index 80af8b39a..8c85113c0 100644 --- a/KEMField/Source/Plugins/VTKPart2/src/KMagnetostaticFieldmap.cc +++ b/KEMField/Source/Plugins/VTKPart2/src/KMagnetostaticFieldmap.cc @@ -697,6 +697,13 @@ void KMagnetostaticFieldmapCalculator::Execute() { tField.SetComponents(fFieldData->GetTuple3(j)); tHasValue = true; + + if (tMirrorPoint[0] != tPoint[0]) + tField[0] *= -1; + if (tMirrorPoint[1] != tPoint[1]) + tField[1] *= -1; + if (tMirrorPoint[2] != tPoint[2]) + tField[2] *= -1; } } } @@ -763,8 +770,9 @@ void KMagnetostaticFieldmapCalculator::Execute() unsigned int j = fGrid->FindPoint(tMirrorPoint); if (fValidityData->GetTuple1(j) >= 3) // 3 = gradient valid { - tGradient.SetComponents(fGradientData->GetTuple9(j)); - tHasValue = true; + // FIXME: mirroring gradients is incorrect, need to flip signs for some components! + //tGradient.SetComponents(fGradientData->GetTuple9(j)); + //tHasValue = true; } } } diff --git a/KEMField/Source/Plugins/VTKPart2/src/KVTKViewerAsBoundaryFieldVisitor.cc b/KEMField/Source/Plugins/VTKPart2/src/KVTKViewerAsBoundaryFieldVisitor.cc index 7036fb249..bcf09e121 100644 --- a/KEMField/Source/Plugins/VTKPart2/src/KVTKViewerAsBoundaryFieldVisitor.cc +++ b/KEMField/Source/Plugins/VTKPart2/src/KVTKViewerAsBoundaryFieldVisitor.cc @@ -11,6 +11,8 @@ #include "KEMVTKViewer.hh" #endif +#include "KFile.h" + #include "KEMCoreMessage.hh" #include "KMPIEnvironment.hh" @@ -20,7 +22,8 @@ namespace KEMField KVTKViewerAsBoundaryFieldVisitor::KVTKViewerAsBoundaryFieldVisitor() : fViewGeometry(false), fSaveGeometry(false), - fFile("ElectrostaticGeometry.vtp") + fFile("ElectrostaticGeometry.vtp"), + fPath() {} KVTKViewerAsBoundaryFieldVisitor::~KVTKViewerAsBoundaryFieldVisitor() = default; @@ -40,8 +43,19 @@ void KVTKViewerAsBoundaryFieldVisitor::PostVisit(KElectrostaticBoundaryField& el if (fViewGeometry) viewer.ViewGeometry(); if (fSaveGeometry) { - kem_cout << "Saving electrode geometry to " << fFile << "." << eom; - viewer.GenerateGeometryFile(fFile); + std::string tFileName; + + if (fFile.length() > 0) { + if (!fPath.empty()) { + tFileName = std::string(fPath) + std::string("/") + fFile; + } + else { + tFileName = std::string(SCRATCH_DEFAULT_DIR) + std::string("/") + fFile; + } + } + + kem_cout << "Saving electrode geometry to <" << tFileName << ">" << eom; + viewer.GenerateGeometryFile(tFileName); } } } diff --git a/KEMField/Source/Surfaces/CMakeLists.txt b/KEMField/Source/Surfaces/CMakeLists.txt index f9cde91d5..cd93710a2 100644 --- a/KEMField/Source/Surfaces/CMakeLists.txt +++ b/KEMField/Source/Surfaces/CMakeLists.txt @@ -1,50 +1,54 @@ # CMakeLists for KEMField/Geometry/Surfaces # Author: T.J. Corona -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (SURFACES_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KBasis.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KBoundary.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KConicSection.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectromagneticBasis.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectrostaticBasis.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KLineSegment.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KMagnetostaticBasis.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KRectangle.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KRing.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KShape.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSortedSurfaceContainer.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSurface.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSurfaceAction.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSurfaceContainer.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSurfaceID.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSurfacePrimitive.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSurfaceTypes.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSurfaceVisitors.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSymmetryGroup.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KTriangle.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KBasis.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KBoundary.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KConicSection.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectromagneticBasis.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KElectrostaticBasis.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KLineSegment.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KMagnetostaticBasis.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KRectangle.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KRing.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KShape.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSortedSurfaceContainer.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSurface.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSurfaceAction.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSurfaceContainer.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSurfaceID.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSurfacePrimitive.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSurfaceTypes.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSurfaceVisitors.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSymmetryGroup.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KTriangle.hh # ${CMAKE_CURRENT_SOURCE_DIR}/include/KOrderedSurfaceContainer.hh # ${CMAKE_CURRENT_SOURCE_DIR}/include/KSurfaceOrderingPredicate.hh - ${CMAKE_CURRENT_SOURCE_DIR}/include/KSolidAngle.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KSolidAngle.hh ) set (SURFACES_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/src/KConicSection.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KLineSegment.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KRectangle.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KRing.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KSortedSurfaceContainer.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KSurface.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KSurfaceContainer.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KTriangle.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/KSolidAngle.cc - ) - -################################################## + ${CMAKE_CURRENT_SOURCE_DIR}/src/KConicSection.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KLineSegment.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KRectangle.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KRing.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KSortedSurfaceContainer.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KSurface.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KSurfaceContainer.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KTriangle.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/KSolidAngle.cc +) -add_library (KEMSurfaces SHARED ${SURFACES_SOURCEFILES} ${SURFACES_HEADERFILES}) -target_link_libraries (KEMSurfaces KEMCore KEMMath KEMIO ${Kommon_LIBRARIES} ${KGeoBag_LIBRARIES}) +add_library (KEMSurfaces SHARED + ${SURFACES_SOURCEFILES} ${SURFACES_HEADERFILES}) +target_include_directories(KEMSurfaces + PUBLIC $ $) +target_link_libraries (KEMSurfaces + PUBLIC + KEMCore + KEMMath + KEMIO +) kasper_install_headers (${SURFACES_HEADERFILES}) kasper_install_libraries (KEMSurfaces) diff --git a/KEMField/Source/Surfaces/include/KConicSection.hh b/KEMField/Source/Surfaces/include/KConicSection.hh index f0b7ca0cb..6d1b4c8ed 100644 --- a/KEMField/Source/Surfaces/include/KConicSection.hh +++ b/KEMField/Source/Surfaces/include/KConicSection.hh @@ -1,8 +1,8 @@ #ifndef KCONICSECTION_DEF #define KCONICSECTION_DEF -#include "../../../Surfaces/include/KShape.hh" -#include "../../../Surfaces/include/KSymmetryGroup.hh" +#include "KShape.hh" +#include "KSymmetryGroup.hh" namespace KEMField { diff --git a/KEMField/Source/Surfaces/include/KElectromagneticBasis.hh b/KEMField/Source/Surfaces/include/KElectromagneticBasis.hh index 7fc875d5e..b96218f9f 100644 --- a/KEMField/Source/Surfaces/include/KElectromagneticBasis.hh +++ b/KEMField/Source/Surfaces/include/KElectromagneticBasis.hh @@ -1,7 +1,7 @@ #ifndef KELECTROMAGNETICBASIS_DEF #define KELECTROMAGNETICBASIS_DEF -#include "../../../Surfaces/include/KBasis.hh" +#include "KBasis.hh" #include #include diff --git a/KEMField/Source/Surfaces/include/KElectrostaticBasis.hh b/KEMField/Source/Surfaces/include/KElectrostaticBasis.hh index a686c584b..5652322d4 100644 --- a/KEMField/Source/Surfaces/include/KElectrostaticBasis.hh +++ b/KEMField/Source/Surfaces/include/KElectrostaticBasis.hh @@ -1,7 +1,7 @@ #ifndef KELECTROSTATICBASIS_DEF #define KELECTROSTATICBASIS_DEF -#include "../../../Surfaces/include/KBasis.hh" +#include "KBasis.hh" #include diff --git a/KEMField/Source/Surfaces/include/KLineSegment.hh b/KEMField/Source/Surfaces/include/KLineSegment.hh index 74f7fb9e3..356cf0d57 100644 --- a/KEMField/Source/Surfaces/include/KLineSegment.hh +++ b/KEMField/Source/Surfaces/include/KLineSegment.hh @@ -1,8 +1,8 @@ #ifndef KLINESEGMENT_DEF #define KLINESEGMENT_DEF -#include "../../../Surfaces/include/KShape.hh" -#include "../../../Surfaces/include/KSymmetryGroup.hh" +#include "KShape.hh" +#include "KSymmetryGroup.hh" namespace KEMField { diff --git a/KEMField/Source/Surfaces/include/KMagnetostaticBasis.hh b/KEMField/Source/Surfaces/include/KMagnetostaticBasis.hh index 49f248dc0..5ef1529e8 100644 --- a/KEMField/Source/Surfaces/include/KMagnetostaticBasis.hh +++ b/KEMField/Source/Surfaces/include/KMagnetostaticBasis.hh @@ -1,7 +1,7 @@ #ifndef KMAGNETOSTATICBASIS_DEF #define KMAGNETOSTATICBASIS_DEF -#include "../../../Surfaces/include/KBasis.hh" +#include "KBasis.hh" #include diff --git a/KEMField/Source/Surfaces/include/KOrderedSurfaceContainer.hh b/KEMField/Source/Surfaces/include/KOrderedSurfaceContainer.hh index d2c435db1..a959a2305 100644 --- a/KEMField/Source/Surfaces/include/KOrderedSurfaceContainer.hh +++ b/KEMField/Source/Surfaces/include/KOrderedSurfaceContainer.hh @@ -1,8 +1,8 @@ #ifndef KOrderedSurfaceContainer_DEF #define KOrderedSurfaceContainer_DEF -#include "../../../Surfaces/include/KSurfaceContainer.hh" -#include "../../../Surfaces/include/KSurfaceOrderingPredicate.hh" +#include "KSurfaceContainer.hh" +#include "KSurfaceOrderingPredicate.hh" #include #include diff --git a/KEMField/Source/Surfaces/include/KRectangle.hh b/KEMField/Source/Surfaces/include/KRectangle.hh index a494781bf..4e4037f25 100644 --- a/KEMField/Source/Surfaces/include/KRectangle.hh +++ b/KEMField/Source/Surfaces/include/KRectangle.hh @@ -1,8 +1,8 @@ #ifndef KRECTANGLE_DEF #define KRECTANGLE_DEF -#include "../../../Surfaces/include/KShape.hh" -#include "../../../Surfaces/include/KSymmetryGroup.hh" +#include "KShape.hh" +#include "KSymmetryGroup.hh" namespace KEMField { diff --git a/KEMField/Source/Surfaces/include/KRing.hh b/KEMField/Source/Surfaces/include/KRing.hh index 137507b62..01a54ccac 100644 --- a/KEMField/Source/Surfaces/include/KRing.hh +++ b/KEMField/Source/Surfaces/include/KRing.hh @@ -1,8 +1,8 @@ #ifndef KRING_DEF #define KRING_DEF -#include "../../../Surfaces/include/KShape.hh" -#include "../../../Surfaces/include/KSymmetryGroup.hh" +#include "KShape.hh" +#include "KSymmetryGroup.hh" namespace KEMField { diff --git a/KEMField/Source/Surfaces/include/KSortedSurfaceContainer.hh b/KEMField/Source/Surfaces/include/KSortedSurfaceContainer.hh index 571d3a1d5..97725bf98 100644 --- a/KEMField/Source/Surfaces/include/KSortedSurfaceContainer.hh +++ b/KEMField/Source/Surfaces/include/KSortedSurfaceContainer.hh @@ -1,7 +1,7 @@ #ifndef KSORTEDSURFACECONTAINER_DEF #define KSORTEDSURFACECONTAINER_DEF -#include "../../../Surfaces/include/KSurfaceContainer.hh" +#include "KSurfaceContainer.hh" namespace KEMField { diff --git a/KEMField/Source/Surfaces/include/KSurface.hh b/KEMField/Source/Surfaces/include/KSurface.hh index d313c2fd5..f9429f3b8 100644 --- a/KEMField/Source/Surfaces/include/KSurface.hh +++ b/KEMField/Source/Surfaces/include/KSurface.hh @@ -1,9 +1,9 @@ #ifndef KSURFACE_DEF #define KSURFACE_DEF -#include "../../../Surfaces/include/KSurfaceID.hh" -#include "../../../Surfaces/include/KSurfacePrimitive.hh" -#include "../../../Surfaces/include/KSurfaceVisitors.hh" +#include "KSurfaceID.hh" +#include "KSurfacePrimitive.hh" +#include "KSurfaceVisitors.hh" #include #include @@ -133,7 +133,7 @@ Stream& operator<<(Stream& s, const KSurface diff --git a/KEMField/Source/Surfaces/include/KSurfaceOrderingPredicate.hh b/KEMField/Source/Surfaces/include/KSurfaceOrderingPredicate.hh index f07232550..a2803b25d 100644 --- a/KEMField/Source/Surfaces/include/KSurfaceOrderingPredicate.hh +++ b/KEMField/Source/Surfaces/include/KSurfaceOrderingPredicate.hh @@ -1,8 +1,8 @@ #ifndef KSurfaceOrderingPredicate_HH__ #define KSurfaceOrderingPredicate_HH__ -#include "../../../Surfaces/include/KSurfaceContainer.hh" -#include "../../../Surfaces/include/KSurfaceVisitors.hh" +#include "KSurfaceContainer.hh" +#include "KSurfaceVisitors.hh" namespace KEMField { diff --git a/KEMField/Source/Surfaces/include/KSurfaceTypes.hh b/KEMField/Source/Surfaces/include/KSurfaceTypes.hh index b3a73a0ee..dadf55845 100644 --- a/KEMField/Source/Surfaces/include/KSurfaceTypes.hh +++ b/KEMField/Source/Surfaces/include/KSurfaceTypes.hh @@ -85,16 +85,16 @@ using KBoundaryTypes = NoDuplicates::Result; using KShapeTypes = NoDuplicates::Result; } // namespace KEMField -#include "../../../Surfaces/include/KBoundary.hh" -#include "../../../Surfaces/include/KConicSection.hh" -#include "../../../Surfaces/include/KElectromagneticBasis.hh" -#include "../../../Surfaces/include/KElectrostaticBasis.hh" -#include "../../../Surfaces/include/KLineSegment.hh" -#include "../../../Surfaces/include/KMagnetostaticBasis.hh" -#include "../../../Surfaces/include/KRectangle.hh" -#include "../../../Surfaces/include/KRing.hh" -#include "../../../Surfaces/include/KSurfaceVisitors.hh" -#include "../../../Surfaces/include/KSymmetryGroup.hh" -#include "../../../Surfaces/include/KTriangle.hh" +#include "KBoundary.hh" +#include "KConicSection.hh" +#include "KElectromagneticBasis.hh" +#include "KElectrostaticBasis.hh" +#include "KLineSegment.hh" +#include "KMagnetostaticBasis.hh" +#include "KRectangle.hh" +#include "KRing.hh" +#include "KSurfaceVisitors.hh" +#include "KSymmetryGroup.hh" +#include "KTriangle.hh" #endif /* KSURFACETYPES_DEF */ diff --git a/KEMField/Source/Surfaces/include/KSurfaceVisitors.hh b/KEMField/Source/Surfaces/include/KSurfaceVisitors.hh index b6d249925..7470c5375 100644 --- a/KEMField/Source/Surfaces/include/KSurfaceVisitors.hh +++ b/KEMField/Source/Surfaces/include/KSurfaceVisitors.hh @@ -1,7 +1,7 @@ #ifndef KSURFACEVISITORS_DEF #define KSURFACEVISITORS_DEF -#include "../../../Surfaces/include/KSurfaceTypes.hh" +#include "KSurfaceTypes.hh" #include "KTypelistVisitor.hh" namespace KEMField diff --git a/KEMField/Source/Surfaces/include/KSymmetryGroup.hh b/KEMField/Source/Surfaces/include/KSymmetryGroup.hh index 46f39dbc6..378515639 100644 --- a/KEMField/Source/Surfaces/include/KSymmetryGroup.hh +++ b/KEMField/Source/Surfaces/include/KSymmetryGroup.hh @@ -1,7 +1,7 @@ #ifndef KSYMMETRYGROUP_DEF #define KSYMMETRYGROUP_DEF -#include "../../../Surfaces/include/KShape.hh" +#include "KShape.hh" #include "KEMConstants.hh" #include "KEMTransformation.hh" diff --git a/KEMField/Source/Surfaces/include/KTriangle.hh b/KEMField/Source/Surfaces/include/KTriangle.hh index a29d0e30e..7fd0c34ec 100644 --- a/KEMField/Source/Surfaces/include/KTriangle.hh +++ b/KEMField/Source/Surfaces/include/KTriangle.hh @@ -1,8 +1,8 @@ #ifndef KTRIANGLE_DEF #define KTRIANGLE_DEF -#include "../../../Surfaces/include/KShape.hh" -#include "../../../Surfaces/include/KSymmetryGroup.hh" +#include "KShape.hh" +#include "KSymmetryGroup.hh" namespace KEMField { diff --git a/KEMField/Source/Surfaces/src/KConicSection.cc b/KEMField/Source/Surfaces/src/KConicSection.cc index 7034b6f67..485e33489 100644 --- a/KEMField/Source/Surfaces/src/KConicSection.cc +++ b/KEMField/Source/Surfaces/src/KConicSection.cc @@ -1,4 +1,4 @@ -#include "../../../Surfaces/include/KConicSection.hh" +#include "KConicSection.hh" #include "KEMConstants.hh" diff --git a/KEMField/Source/Surfaces/src/KLineSegment.cc b/KEMField/Source/Surfaces/src/KLineSegment.cc index deb925b1b..9d1809ad2 100644 --- a/KEMField/Source/Surfaces/src/KLineSegment.cc +++ b/KEMField/Source/Surfaces/src/KLineSegment.cc @@ -1,4 +1,4 @@ -#include "../../../Surfaces/include/KLineSegment.hh" +#include "KLineSegment.hh" #include diff --git a/KEMField/Source/Surfaces/src/KOrderedSurfaceContainer.cc b/KEMField/Source/Surfaces/src/KOrderedSurfaceContainer.cc index 43b15c4c4..9ed87a1e1 100644 --- a/KEMField/Source/Surfaces/src/KOrderedSurfaceContainer.cc +++ b/KEMField/Source/Surfaces/src/KOrderedSurfaceContainer.cc @@ -1,4 +1,4 @@ -#include "../../../Surfaces/include/KOrderedSurfaceContainer.hh" +#include "KOrderedSurfaceContainer.hh" #include diff --git a/KEMField/Source/Surfaces/src/KRectangle.cc b/KEMField/Source/Surfaces/src/KRectangle.cc index ac57e77a6..bae455e9d 100644 --- a/KEMField/Source/Surfaces/src/KRectangle.cc +++ b/KEMField/Source/Surfaces/src/KRectangle.cc @@ -1,4 +1,4 @@ -#include "../../../Surfaces/include/KRectangle.hh" +#include "KRectangle.hh" #include diff --git a/KEMField/Source/Surfaces/src/KRing.cc b/KEMField/Source/Surfaces/src/KRing.cc index 18dd7636d..936551765 100644 --- a/KEMField/Source/Surfaces/src/KRing.cc +++ b/KEMField/Source/Surfaces/src/KRing.cc @@ -1,6 +1,6 @@ -#include "../../../Surfaces/include/KRing.hh" +#include "KRing.hh" -#include "../../../Surfaces/include/KSurfaceVisitors.hh" +#include "KSurfaceVisitors.hh" #include "KEMConstants.hh" namespace KEMField diff --git a/KEMField/Source/Surfaces/src/KSortedSurfaceContainer.cc b/KEMField/Source/Surfaces/src/KSortedSurfaceContainer.cc index db2d78fea..cb2b4f962 100644 --- a/KEMField/Source/Surfaces/src/KSortedSurfaceContainer.cc +++ b/KEMField/Source/Surfaces/src/KSortedSurfaceContainer.cc @@ -1,4 +1,4 @@ -#include "../../../Surfaces/include/KSortedSurfaceContainer.hh" +#include "KSortedSurfaceContainer.hh" #include diff --git a/KEMField/Source/Surfaces/src/KSurface.cc b/KEMField/Source/Surfaces/src/KSurface.cc index 941b6929d..51edfc424 100644 --- a/KEMField/Source/Surfaces/src/KSurface.cc +++ b/KEMField/Source/Surfaces/src/KSurface.cc @@ -1,4 +1,4 @@ -#include "../../../Surfaces/include/KSurface.hh" +#include "KSurface.hh" #include "KDataComparator.hh" diff --git a/KEMField/Source/Surfaces/src/KSurfaceContainer.cc b/KEMField/Source/Surfaces/src/KSurfaceContainer.cc index 579e55ec8..eeace8528 100644 --- a/KEMField/Source/Surfaces/src/KSurfaceContainer.cc +++ b/KEMField/Source/Surfaces/src/KSurfaceContainer.cc @@ -1,4 +1,4 @@ -#include "../../../Surfaces/include/KSurfaceContainer.hh" +#include "KSurfaceContainer.hh" namespace KEMField { diff --git a/KEMField/Source/Surfaces/src/KTriangle.cc b/KEMField/Source/Surfaces/src/KTriangle.cc index 095396493..371866c6d 100644 --- a/KEMField/Source/Surfaces/src/KTriangle.cc +++ b/KEMField/Source/Surfaces/src/KTriangle.cc @@ -1,6 +1,6 @@ -#include "../../../Surfaces/include/KTriangle.hh" +#include "KTriangle.hh" -#include "../../../Surfaces/include/KSurfaceVisitors.hh" +#include "KSurfaceVisitors.hh" namespace KEMField { diff --git a/KEMField/Source/Visualization/CMakeLists.txt b/KEMField/Source/Visualization/CMakeLists.txt index c8735ab3d..063bef6a3 100644 --- a/KEMField/Source/Visualization/CMakeLists.txt +++ b/KEMField/Source/Visualization/CMakeLists.txt @@ -1,21 +1,22 @@ # CMakeLists for KEMField/Visualization # Author: T.J. Corona -kasper_internal_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) - set (KEMVISUALIZATION_HEADERFILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMFieldCanvas.hh + ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMFieldCanvas.hh ) set (KEMVISUALIZATION_SOURCEFILES - ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMFieldCanvas.cc - ) - -################################################## + ${CMAKE_CURRENT_SOURCE_DIR}/src/KEMFieldCanvas.cc +) -add_library (KEMVisualization SHARED ${KEMVISUALIZATION_SOURCEFILES} ${KEMVISUALIZATION_HEADERFILES}) -target_link_libraries (KEMVisualization KEMCore) +add_library (KEMVisualization SHARED + ${KEMVISUALIZATION_SOURCEFILES} ${KEMVISUALIZATION_HEADERFILES}) +target_include_directories(KEMVisualization + PUBLIC $ $) +target_link_libraries (KEMVisualization + PUBLIC + KEMCore +) kasper_install_headers (${KEMVISUALIZATION_HEADERFILES}) kasper_install_libraries (KEMVisualization) - diff --git a/KEMField/opencl/1.1/CL/cl.h b/KEMField/opencl/1.1/CL/cl.h deleted file mode 100644 index 4f21afe55..000000000 --- a/KEMField/opencl/1.1/CL/cl.h +++ /dev/null @@ -1,998 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008-2010 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and/or associated documentation files (the - * "Materials"), to deal in the Materials without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Materials, and to - * permit persons to whom the Materials are 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 Materials. - * - * THE MATERIALS ARE 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 - * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. - ******************************************************************************/ - -/* $Revision: 11985 $ on $Date: 2010-07-15 11:16:06 -0700 (Thu, 15 Jul 2010) $ */ - -#ifndef __OPENCL_CL_H -#define __OPENCL_CL_H - -#ifdef __APPLE__ -#include -#else -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/******************************************************************************/ - -typedef struct _cl_platform_id * cl_platform_id; -typedef struct _cl_device_id * cl_device_id; -typedef struct _cl_context * cl_context; -typedef struct _cl_command_queue * cl_command_queue; -typedef struct _cl_mem * cl_mem; -typedef struct _cl_program * cl_program; -typedef struct _cl_kernel * cl_kernel; -typedef struct _cl_event * cl_event; -typedef struct _cl_sampler * cl_sampler; - -typedef cl_uint cl_bool; /* WARNING! Unlike cl_ types in cl_platform.h, cl_bool is not guaranteed to be the same size as the bool in kernels. */ -typedef cl_ulong cl_bitfield; -typedef cl_bitfield cl_device_type; -typedef cl_uint cl_platform_info; -typedef cl_uint cl_device_info; -typedef cl_bitfield cl_device_fp_config; -typedef cl_uint cl_device_mem_cache_type; -typedef cl_uint cl_device_local_mem_type; -typedef cl_bitfield cl_device_exec_capabilities; -typedef cl_bitfield cl_command_queue_properties; - -typedef intptr_t cl_context_properties; -typedef cl_uint cl_context_info; -typedef cl_uint cl_command_queue_info; -typedef cl_uint cl_channel_order; -typedef cl_uint cl_channel_type; -typedef cl_bitfield cl_mem_flags; -typedef cl_uint cl_mem_object_type; -typedef cl_uint cl_mem_info; -typedef cl_uint cl_image_info; -typedef cl_uint cl_buffer_create_type; -typedef cl_uint cl_addressing_mode; -typedef cl_uint cl_filter_mode; -typedef cl_uint cl_sampler_info; -typedef cl_bitfield cl_map_flags; -typedef cl_uint cl_program_info; -typedef cl_uint cl_program_build_info; -typedef cl_int cl_build_status; -typedef cl_uint cl_kernel_info; -typedef cl_uint cl_kernel_work_group_info; -typedef cl_uint cl_event_info; -typedef cl_uint cl_command_type; -typedef cl_uint cl_profiling_info; - -typedef struct _cl_image_format { - cl_channel_order image_channel_order; - cl_channel_type image_channel_data_type; -} cl_image_format; - - -typedef struct _cl_buffer_region { - size_t origin; - size_t size; -} cl_buffer_region; - -/******************************************************************************/ - -/* Error Codes */ -#define CL_SUCCESS 0 -#define CL_DEVICE_NOT_FOUND -1 -#define CL_DEVICE_NOT_AVAILABLE -2 -#define CL_COMPILER_NOT_AVAILABLE -3 -#define CL_MEM_OBJECT_ALLOCATION_FAILURE -4 -#define CL_OUT_OF_RESOURCES -5 -#define CL_OUT_OF_HOST_MEMORY -6 -#define CL_PROFILING_INFO_NOT_AVAILABLE -7 -#define CL_MEM_COPY_OVERLAP -8 -#define CL_IMAGE_FORMAT_MISMATCH -9 -#define CL_IMAGE_FORMAT_NOT_SUPPORTED -10 -#define CL_BUILD_PROGRAM_FAILURE -11 -#define CL_MAP_FAILURE -12 -#define CL_MISALIGNED_SUB_BUFFER_OFFSET -13 -#define CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST -14 - -#define CL_INVALID_VALUE -30 -#define CL_INVALID_DEVICE_TYPE -31 -#define CL_INVALID_PLATFORM -32 -#define CL_INVALID_DEVICE -33 -#define CL_INVALID_CONTEXT -34 -#define CL_INVALID_QUEUE_PROPERTIES -35 -#define CL_INVALID_COMMAND_QUEUE -36 -#define CL_INVALID_HOST_PTR -37 -#define CL_INVALID_MEM_OBJECT -38 -#define CL_INVALID_IMAGE_FORMAT_DESCRIPTOR -39 -#define CL_INVALID_IMAGE_SIZE -40 -#define CL_INVALID_SAMPLER -41 -#define CL_INVALID_BINARY -42 -#define CL_INVALID_BUILD_OPTIONS -43 -#define CL_INVALID_PROGRAM -44 -#define CL_INVALID_PROGRAM_EXECUTABLE -45 -#define CL_INVALID_KERNEL_NAME -46 -#define CL_INVALID_KERNEL_DEFINITION -47 -#define CL_INVALID_KERNEL -48 -#define CL_INVALID_ARG_INDEX -49 -#define CL_INVALID_ARG_VALUE -50 -#define CL_INVALID_ARG_SIZE -51 -#define CL_INVALID_KERNEL_ARGS -52 -#define CL_INVALID_WORK_DIMENSION -53 -#define CL_INVALID_WORK_GROUP_SIZE -54 -#define CL_INVALID_WORK_ITEM_SIZE -55 -#define CL_INVALID_GLOBAL_OFFSET -56 -#define CL_INVALID_EVENT_WAIT_LIST -57 -#define CL_INVALID_EVENT -58 -#define CL_INVALID_OPERATION -59 -#define CL_INVALID_GL_OBJECT -60 -#define CL_INVALID_BUFFER_SIZE -61 -#define CL_INVALID_MIP_LEVEL -62 -#define CL_INVALID_GLOBAL_WORK_SIZE -63 -#define CL_INVALID_PROPERTY -64 - -/* OpenCL Version */ -#define CL_VERSION_1_0 1 -#define CL_VERSION_1_1 1 - -/* cl_bool */ -#define CL_FALSE 0 -#define CL_TRUE 1 - -/* cl_platform_info */ -#define CL_PLATFORM_PROFILE 0x0900 -#define CL_PLATFORM_VERSION 0x0901 -#define CL_PLATFORM_NAME 0x0902 -#define CL_PLATFORM_VENDOR 0x0903 -#define CL_PLATFORM_EXTENSIONS 0x0904 - -/* cl_device_type - bitfield */ -#define CL_DEVICE_TYPE_DEFAULT (1 << 0) -#define CL_DEVICE_TYPE_CPU (1 << 1) -#define CL_DEVICE_TYPE_GPU (1 << 2) -#define CL_DEVICE_TYPE_ACCELERATOR (1 << 3) -#define CL_DEVICE_TYPE_ALL 0xFFFFFFFF - -/* cl_device_info */ -#define CL_DEVICE_TYPE 0x1000 -#define CL_DEVICE_VENDOR_ID 0x1001 -#define CL_DEVICE_MAX_COMPUTE_UNITS 0x1002 -#define CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS 0x1003 -#define CL_DEVICE_MAX_WORK_GROUP_SIZE 0x1004 -#define CL_DEVICE_MAX_WORK_ITEM_SIZES 0x1005 -#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR 0x1006 -#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT 0x1007 -#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT 0x1008 -#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG 0x1009 -#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT 0x100A -#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE 0x100B -#define CL_DEVICE_MAX_CLOCK_FREQUENCY 0x100C -#define CL_DEVICE_ADDRESS_BITS 0x100D -#define CL_DEVICE_MAX_READ_IMAGE_ARGS 0x100E -#define CL_DEVICE_MAX_WRITE_IMAGE_ARGS 0x100F -#define CL_DEVICE_MAX_MEM_ALLOC_SIZE 0x1010 -#define CL_DEVICE_IMAGE2D_MAX_WIDTH 0x1011 -#define CL_DEVICE_IMAGE2D_MAX_HEIGHT 0x1012 -#define CL_DEVICE_IMAGE3D_MAX_WIDTH 0x1013 -#define CL_DEVICE_IMAGE3D_MAX_HEIGHT 0x1014 -#define CL_DEVICE_IMAGE3D_MAX_DEPTH 0x1015 -#define CL_DEVICE_IMAGE_SUPPORT 0x1016 -#define CL_DEVICE_MAX_PARAMETER_SIZE 0x1017 -#define CL_DEVICE_MAX_SAMPLERS 0x1018 -#define CL_DEVICE_MEM_BASE_ADDR_ALIGN 0x1019 -#define CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE 0x101A -#define CL_DEVICE_SINGLE_FP_CONFIG 0x101B -#define CL_DEVICE_GLOBAL_MEM_CACHE_TYPE 0x101C -#define CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE 0x101D -#define CL_DEVICE_GLOBAL_MEM_CACHE_SIZE 0x101E -#define CL_DEVICE_GLOBAL_MEM_SIZE 0x101F -#define CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE 0x1020 -#define CL_DEVICE_MAX_CONSTANT_ARGS 0x1021 -#define CL_DEVICE_LOCAL_MEM_TYPE 0x1022 -#define CL_DEVICE_LOCAL_MEM_SIZE 0x1023 -#define CL_DEVICE_ERROR_CORRECTION_SUPPORT 0x1024 -#define CL_DEVICE_PROFILING_TIMER_RESOLUTION 0x1025 -#define CL_DEVICE_ENDIAN_LITTLE 0x1026 -#define CL_DEVICE_AVAILABLE 0x1027 -#define CL_DEVICE_COMPILER_AVAILABLE 0x1028 -#define CL_DEVICE_EXECUTION_CAPABILITIES 0x1029 -#define CL_DEVICE_QUEUE_PROPERTIES 0x102A -#define CL_DEVICE_NAME 0x102B -#define CL_DEVICE_VENDOR 0x102C -#define CL_DRIVER_VERSION 0x102D -#define CL_DEVICE_PROFILE 0x102E -#define CL_DEVICE_VERSION 0x102F -#define CL_DEVICE_EXTENSIONS 0x1030 -#define CL_DEVICE_PLATFORM 0x1031 -/* 0x1032 reserved for CL_DEVICE_DOUBLE_FP_CONFIG */ -/* 0x1033 reserved for CL_DEVICE_HALF_FP_CONFIG */ -#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF 0x1034 -#define CL_DEVICE_HOST_UNIFIED_MEMORY 0x1035 -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR 0x1036 -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT 0x1037 -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_INT 0x1038 -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG 0x1039 -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT 0x103A -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE 0x103B -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF 0x103C -#define CL_DEVICE_OPENCL_C_VERSION 0x103D - -/* cl_device_fp_config - bitfield */ -#define CL_FP_DENORM (1 << 0) -#define CL_FP_INF_NAN (1 << 1) -#define CL_FP_ROUND_TO_NEAREST (1 << 2) -#define CL_FP_ROUND_TO_ZERO (1 << 3) -#define CL_FP_ROUND_TO_INF (1 << 4) -#define CL_FP_FMA (1 << 5) -#define CL_FP_SOFT_FLOAT (1 << 6) - -/* cl_device_mem_cache_type */ -#define CL_NONE 0x0 -#define CL_READ_ONLY_CACHE 0x1 -#define CL_READ_WRITE_CACHE 0x2 - -/* cl_device_local_mem_type */ -#define CL_LOCAL 0x1 -#define CL_GLOBAL 0x2 - -/* cl_device_exec_capabilities - bitfield */ -#define CL_EXEC_KERNEL (1 << 0) -#define CL_EXEC_NATIVE_KERNEL (1 << 1) - -/* cl_command_queue_properties - bitfield */ -#define CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE (1 << 0) -#define CL_QUEUE_PROFILING_ENABLE (1 << 1) - -/* cl_context_info */ -#define CL_CONTEXT_REFERENCE_COUNT 0x1080 -#define CL_CONTEXT_DEVICES 0x1081 -#define CL_CONTEXT_PROPERTIES 0x1082 -#define CL_CONTEXT_NUM_DEVICES 0x1083 - -/* cl_context_info + cl_context_properties */ -#define CL_CONTEXT_PLATFORM 0x1084 - -/* cl_command_queue_info */ -#define CL_QUEUE_CONTEXT 0x1090 -#define CL_QUEUE_DEVICE 0x1091 -#define CL_QUEUE_REFERENCE_COUNT 0x1092 -#define CL_QUEUE_PROPERTIES 0x1093 - -/* cl_mem_flags - bitfield */ -#define CL_MEM_READ_WRITE (1 << 0) -#define CL_MEM_WRITE_ONLY (1 << 1) -#define CL_MEM_READ_ONLY (1 << 2) -#define CL_MEM_USE_HOST_PTR (1 << 3) -#define CL_MEM_ALLOC_HOST_PTR (1 << 4) -#define CL_MEM_COPY_HOST_PTR (1 << 5) - -/* cl_channel_order */ -#define CL_R 0x10B0 -#define CL_A 0x10B1 -#define CL_RG 0x10B2 -#define CL_RA 0x10B3 -#define CL_RGB 0x10B4 -#define CL_RGBA 0x10B5 -#define CL_BGRA 0x10B6 -#define CL_ARGB 0x10B7 -#define CL_INTENSITY 0x10B8 -#define CL_LUMINANCE 0x10B9 -#define CL_Rx 0x10BA -#define CL_RGx 0x10BB -#define CL_RGBx 0x10BC - -/* cl_channel_type */ -#define CL_SNORM_INT8 0x10D0 -#define CL_SNORM_INT16 0x10D1 -#define CL_UNORM_INT8 0x10D2 -#define CL_UNORM_INT16 0x10D3 -#define CL_UNORM_SHORT_565 0x10D4 -#define CL_UNORM_SHORT_555 0x10D5 -#define CL_UNORM_INT_101010 0x10D6 -#define CL_SIGNED_INT8 0x10D7 -#define CL_SIGNED_INT16 0x10D8 -#define CL_SIGNED_INT32 0x10D9 -#define CL_UNSIGNED_INT8 0x10DA -#define CL_UNSIGNED_INT16 0x10DB -#define CL_UNSIGNED_INT32 0x10DC -#define CL_HALF_FLOAT 0x10DD -#define CL_FLOAT 0x10DE - -/* cl_mem_object_type */ -#define CL_MEM_OBJECT_BUFFER 0x10F0 -#define CL_MEM_OBJECT_IMAGE2D 0x10F1 -#define CL_MEM_OBJECT_IMAGE3D 0x10F2 - -/* cl_mem_info */ -#define CL_MEM_TYPE 0x1100 -#define CL_MEM_FLAGS 0x1101 -#define CL_MEM_SIZE 0x1102 -#define CL_MEM_HOST_PTR 0x1103 -#define CL_MEM_MAP_COUNT 0x1104 -#define CL_MEM_REFERENCE_COUNT 0x1105 -#define CL_MEM_CONTEXT 0x1106 -#define CL_MEM_ASSOCIATED_MEMOBJECT 0x1107 -#define CL_MEM_OFFSET 0x1108 - -/* cl_image_info */ -#define CL_IMAGE_FORMAT 0x1110 -#define CL_IMAGE_ELEMENT_SIZE 0x1111 -#define CL_IMAGE_ROW_PITCH 0x1112 -#define CL_IMAGE_SLICE_PITCH 0x1113 -#define CL_IMAGE_WIDTH 0x1114 -#define CL_IMAGE_HEIGHT 0x1115 -#define CL_IMAGE_DEPTH 0x1116 - -/* cl_addressing_mode */ -#define CL_ADDRESS_NONE 0x1130 -#define CL_ADDRESS_CLAMP_TO_EDGE 0x1131 -#define CL_ADDRESS_CLAMP 0x1132 -#define CL_ADDRESS_REPEAT 0x1133 -#define CL_ADDRESS_MIRRORED_REPEAT 0x1134 - -/* cl_filter_mode */ -#define CL_FILTER_NEAREST 0x1140 -#define CL_FILTER_LINEAR 0x1141 - -/* cl_sampler_info */ -#define CL_SAMPLER_REFERENCE_COUNT 0x1150 -#define CL_SAMPLER_CONTEXT 0x1151 -#define CL_SAMPLER_NORMALIZED_COORDS 0x1152 -#define CL_SAMPLER_ADDRESSING_MODE 0x1153 -#define CL_SAMPLER_FILTER_MODE 0x1154 - -/* cl_map_flags - bitfield */ -#define CL_MAP_READ (1 << 0) -#define CL_MAP_WRITE (1 << 1) - -/* cl_program_info */ -#define CL_PROGRAM_REFERENCE_COUNT 0x1160 -#define CL_PROGRAM_CONTEXT 0x1161 -#define CL_PROGRAM_NUM_DEVICES 0x1162 -#define CL_PROGRAM_DEVICES 0x1163 -#define CL_PROGRAM_SOURCE 0x1164 -#define CL_PROGRAM_BINARY_SIZES 0x1165 -#define CL_PROGRAM_BINARIES 0x1166 - -/* cl_program_build_info */ -#define CL_PROGRAM_BUILD_STATUS 0x1181 -#define CL_PROGRAM_BUILD_OPTIONS 0x1182 -#define CL_PROGRAM_BUILD_LOG 0x1183 - -/* cl_build_status */ -#define CL_BUILD_SUCCESS 0 -#define CL_BUILD_NONE -1 -#define CL_BUILD_ERROR -2 -#define CL_BUILD_IN_PROGRESS -3 - -/* cl_kernel_info */ -#define CL_KERNEL_FUNCTION_NAME 0x1190 -#define CL_KERNEL_NUM_ARGS 0x1191 -#define CL_KERNEL_REFERENCE_COUNT 0x1192 -#define CL_KERNEL_CONTEXT 0x1193 -#define CL_KERNEL_PROGRAM 0x1194 - -/* cl_kernel_work_group_info */ -#define CL_KERNEL_WORK_GROUP_SIZE 0x11B0 -#define CL_KERNEL_COMPILE_WORK_GROUP_SIZE 0x11B1 -#define CL_KERNEL_LOCAL_MEM_SIZE 0x11B2 -#define CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE 0x11B3 -#define CL_KERNEL_PRIVATE_MEM_SIZE 0x11B4 - -/* cl_event_info */ -#define CL_EVENT_COMMAND_QUEUE 0x11D0 -#define CL_EVENT_COMMAND_TYPE 0x11D1 -#define CL_EVENT_REFERENCE_COUNT 0x11D2 -#define CL_EVENT_COMMAND_EXECUTION_STATUS 0x11D3 -#define CL_EVENT_CONTEXT 0x11D4 - -/* cl_command_type */ -#define CL_COMMAND_NDRANGE_KERNEL 0x11F0 -#define CL_COMMAND_TASK 0x11F1 -#define CL_COMMAND_NATIVE_KERNEL 0x11F2 -#define CL_COMMAND_READ_BUFFER 0x11F3 -#define CL_COMMAND_WRITE_BUFFER 0x11F4 -#define CL_COMMAND_COPY_BUFFER 0x11F5 -#define CL_COMMAND_READ_IMAGE 0x11F6 -#define CL_COMMAND_WRITE_IMAGE 0x11F7 -#define CL_COMMAND_COPY_IMAGE 0x11F8 -#define CL_COMMAND_COPY_IMAGE_TO_BUFFER 0x11F9 -#define CL_COMMAND_COPY_BUFFER_TO_IMAGE 0x11FA -#define CL_COMMAND_MAP_BUFFER 0x11FB -#define CL_COMMAND_MAP_IMAGE 0x11FC -#define CL_COMMAND_UNMAP_MEM_OBJECT 0x11FD -#define CL_COMMAND_MARKER 0x11FE -#define CL_COMMAND_ACQUIRE_GL_OBJECTS 0x11FF -#define CL_COMMAND_RELEASE_GL_OBJECTS 0x1200 -#define CL_COMMAND_READ_BUFFER_RECT 0x1201 -#define CL_COMMAND_WRITE_BUFFER_RECT 0x1202 -#define CL_COMMAND_COPY_BUFFER_RECT 0x1203 -#define CL_COMMAND_USER 0x1204 - -/* command execution status */ -#define CL_COMPLETE 0x0 -#define CL_RUNNING 0x1 -#define CL_SUBMITTED 0x2 -#define CL_QUEUED 0x3 - -/* cl_buffer_create_type */ -#define CL_BUFFER_CREATE_TYPE_REGION 0x1220 - -/* cl_profiling_info */ -#define CL_PROFILING_COMMAND_QUEUED 0x1280 -#define CL_PROFILING_COMMAND_SUBMIT 0x1281 -#define CL_PROFILING_COMMAND_START 0x1282 -#define CL_PROFILING_COMMAND_END 0x1283 - -/********************************************************************************************************/ - -/* Platform API */ -extern CL_API_ENTRY cl_int CL_API_CALL -clGetPlatformIDs(cl_uint /* num_entries */, - cl_platform_id * /* platforms */, - cl_uint * /* num_platforms */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clGetPlatformInfo(cl_platform_id /* platform */, - cl_platform_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -/* Device APIs */ -extern CL_API_ENTRY cl_int CL_API_CALL -clGetDeviceIDs(cl_platform_id /* platform */, - cl_device_type /* device_type */, - cl_uint /* num_entries */, - cl_device_id * /* devices */, - cl_uint * /* num_devices */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clGetDeviceInfo(cl_device_id /* device */, - cl_device_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -/* Context APIs */ -extern CL_API_ENTRY cl_context CL_API_CALL -clCreateContext(const cl_context_properties * /* properties */, - cl_uint /* num_devices */, - const cl_device_id * /* devices */, - void (CL_CALLBACK * /* pfn_notify */)(const char *, const void *, size_t, void *), - void * /* user_data */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_context CL_API_CALL -clCreateContextFromType(const cl_context_properties * /* properties */, - cl_device_type /* device_type */, - void (CL_CALLBACK * /* pfn_notify*/ )(const char *, const void *, size_t, void *), - void * /* user_data */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clRetainContext(cl_context /* context */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clReleaseContext(cl_context /* context */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clGetContextInfo(cl_context /* context */, - cl_context_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -/* Command Queue APIs */ -extern CL_API_ENTRY cl_command_queue CL_API_CALL -clCreateCommandQueue(cl_context /* context */, - cl_device_id /* device */, - cl_command_queue_properties /* properties */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clRetainCommandQueue(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clReleaseCommandQueue(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clGetCommandQueueInfo(cl_command_queue /* command_queue */, - cl_command_queue_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -#ifdef CL_USE_DEPRECATED_OPENCL_1_0_APIS -#warning CL_USE_DEPRECATED_OPENCL_1_0_APIS is defined. These APIs are unsupported and untested in OpenCL 1.1! -/* - * WARNING: - * This API introduces mutable state into the OpenCL implementation. It has been REMOVED - * to better facilitate thread safety. The 1.0 API is not thread safe. It is not tested by the - * OpenCL 1.1 conformance test, and consequently may not work or may not work dependably. - * It is likely to be non-performant. Use of this API is not advised. Use at your own risk. - * - * Software developers previously relying on this API are instructed to set the command queue - * properties when creating the queue, instead. - */ -extern CL_API_ENTRY cl_int CL_API_CALL -clSetCommandQueueProperty(cl_command_queue /* command_queue */, - cl_command_queue_properties /* properties */, - cl_bool /* enable */, - cl_command_queue_properties * /* old_properties */) CL_EXT_SUFFIX__VERSION_1_0_DEPRECATED; -#endif /* CL_USE_DEPRECATED_OPENCL_1_0_APIS */ - -/* Memory Object APIs */ -extern CL_API_ENTRY cl_mem CL_API_CALL -clCreateBuffer(cl_context /* context */, - cl_mem_flags /* flags */, - size_t /* size */, - void * /* host_ptr */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_mem CL_API_CALL -clCreateSubBuffer(cl_mem /* buffer */, - cl_mem_flags /* flags */, - cl_buffer_create_type /* buffer_create_type */, - const void * /* buffer_create_info */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_1; - -extern CL_API_ENTRY cl_mem CL_API_CALL -clCreateImage2D(cl_context /* context */, - cl_mem_flags /* flags */, - const cl_image_format * /* image_format */, - size_t /* image_width */, - size_t /* image_height */, - size_t /* image_row_pitch */, - void * /* host_ptr */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_mem CL_API_CALL -clCreateImage3D(cl_context /* context */, - cl_mem_flags /* flags */, - const cl_image_format * /* image_format */, - size_t /* image_width */, - size_t /* image_height */, - size_t /* image_depth */, - size_t /* image_row_pitch */, - size_t /* image_slice_pitch */, - void * /* host_ptr */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clRetainMemObject(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clReleaseMemObject(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clGetSupportedImageFormats(cl_context /* context */, - cl_mem_flags /* flags */, - cl_mem_object_type /* image_type */, - cl_uint /* num_entries */, - cl_image_format * /* image_formats */, - cl_uint * /* num_image_formats */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clGetMemObjectInfo(cl_mem /* memobj */, - cl_mem_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clGetImageInfo(cl_mem /* image */, - cl_image_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clSetMemObjectDestructorCallback( cl_mem /* memobj */, - void (CL_CALLBACK * /*pfn_notify*/)( cl_mem /* memobj */, void* /*user_data*/), - void * /*user_data */ ) CL_API_SUFFIX__VERSION_1_1; - -/* Sampler APIs */ -extern CL_API_ENTRY cl_sampler CL_API_CALL -clCreateSampler(cl_context /* context */, - cl_bool /* normalized_coords */, - cl_addressing_mode /* addressing_mode */, - cl_filter_mode /* filter_mode */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clRetainSampler(cl_sampler /* sampler */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clReleaseSampler(cl_sampler /* sampler */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clGetSamplerInfo(cl_sampler /* sampler */, - cl_sampler_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -/* Program Object APIs */ -extern CL_API_ENTRY cl_program CL_API_CALL -clCreateProgramWithSource(cl_context /* context */, - cl_uint /* count */, - const char ** /* strings */, - const size_t * /* lengths */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_program CL_API_CALL -clCreateProgramWithBinary(cl_context /* context */, - cl_uint /* num_devices */, - const cl_device_id * /* device_list */, - const size_t * /* lengths */, - const unsigned char ** /* binaries */, - cl_int * /* binary_status */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clRetainProgram(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clReleaseProgram(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clBuildProgram(cl_program /* program */, - cl_uint /* num_devices */, - const cl_device_id * /* device_list */, - const char * /* options */, - void (CL_CALLBACK * /* pfn_notify */)(cl_program /* program */, void * /* user_data */), - void * /* user_data */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clUnloadCompiler(void) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clGetProgramInfo(cl_program /* program */, - cl_program_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clGetProgramBuildInfo(cl_program /* program */, - cl_device_id /* device */, - cl_program_build_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -/* Kernel Object APIs */ -extern CL_API_ENTRY cl_kernel CL_API_CALL -clCreateKernel(cl_program /* program */, - const char * /* kernel_name */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clCreateKernelsInProgram(cl_program /* program */, - cl_uint /* num_kernels */, - cl_kernel * /* kernels */, - cl_uint * /* num_kernels_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clRetainKernel(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clReleaseKernel(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clSetKernelArg(cl_kernel /* kernel */, - cl_uint /* arg_index */, - size_t /* arg_size */, - const void * /* arg_value */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clGetKernelInfo(cl_kernel /* kernel */, - cl_kernel_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clGetKernelWorkGroupInfo(cl_kernel /* kernel */, - cl_device_id /* device */, - cl_kernel_work_group_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -/* Event Object APIs */ -extern CL_API_ENTRY cl_int CL_API_CALL -clWaitForEvents(cl_uint /* num_events */, - const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clGetEventInfo(cl_event /* event */, - cl_event_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_event CL_API_CALL -clCreateUserEvent(cl_context /* context */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_1; - -extern CL_API_ENTRY cl_int CL_API_CALL -clRetainEvent(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clReleaseEvent(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clSetUserEventStatus(cl_event /* event */, - cl_int /* execution_status */) CL_API_SUFFIX__VERSION_1_1; - -extern CL_API_ENTRY cl_int CL_API_CALL -clSetEventCallback( cl_event /* event */, - cl_int /* command_exec_callback_type */, - void (CL_CALLBACK * /* pfn_notify */)(cl_event, cl_int, void *), - void * /* user_data */) CL_API_SUFFIX__VERSION_1_1; - -/* Profiling APIs */ -extern CL_API_ENTRY cl_int CL_API_CALL -clGetEventProfilingInfo(cl_event /* event */, - cl_profiling_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -/* Flush and Finish APIs */ -extern CL_API_ENTRY cl_int CL_API_CALL -clFlush(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clFinish(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; - -/* Enqueued Commands APIs */ -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueReadBuffer(cl_command_queue /* command_queue */, - cl_mem /* buffer */, - cl_bool /* blocking_read */, - size_t /* offset */, - size_t /* cb */, - void * /* ptr */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueReadBufferRect(cl_command_queue /* command_queue */, - cl_mem /* buffer */, - cl_bool /* blocking_read */, - const size_t * /* buffer_origin */, - const size_t * /* host_origin */, - const size_t * /* region */, - size_t /* buffer_row_pitch */, - size_t /* buffer_slice_pitch */, - size_t /* host_row_pitch */, - size_t /* host_slice_pitch */, - void * /* ptr */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_1; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueWriteBuffer(cl_command_queue /* command_queue */, - cl_mem /* buffer */, - cl_bool /* blocking_write */, - size_t /* offset */, - size_t /* cb */, - const void * /* ptr */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueWriteBufferRect(cl_command_queue /* command_queue */, - cl_mem /* buffer */, - cl_bool /* blocking_write */, - const size_t * /* buffer_origin */, - const size_t * /* host_origin */, - const size_t * /* region */, - size_t /* buffer_row_pitch */, - size_t /* buffer_slice_pitch */, - size_t /* host_row_pitch */, - size_t /* host_slice_pitch */, - const void * /* ptr */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_1; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueCopyBuffer(cl_command_queue /* command_queue */, - cl_mem /* src_buffer */, - cl_mem /* dst_buffer */, - size_t /* src_offset */, - size_t /* dst_offset */, - size_t /* cb */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueCopyBufferRect(cl_command_queue /* command_queue */, - cl_mem /* src_buffer */, - cl_mem /* dst_buffer */, - const size_t * /* src_origin */, - const size_t * /* dst_origin */, - const size_t * /* region */, - size_t /* src_row_pitch */, - size_t /* src_slice_pitch */, - size_t /* dst_row_pitch */, - size_t /* dst_slice_pitch */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_1; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueReadImage(cl_command_queue /* command_queue */, - cl_mem /* image */, - cl_bool /* blocking_read */, - const size_t * /* origin[3] */, - const size_t * /* region[3] */, - size_t /* row_pitch */, - size_t /* slice_pitch */, - void * /* ptr */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueWriteImage(cl_command_queue /* command_queue */, - cl_mem /* image */, - cl_bool /* blocking_write */, - const size_t * /* origin[3] */, - const size_t * /* region[3] */, - size_t /* input_row_pitch */, - size_t /* input_slice_pitch */, - const void * /* ptr */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueCopyImage(cl_command_queue /* command_queue */, - cl_mem /* src_image */, - cl_mem /* dst_image */, - const size_t * /* src_origin[3] */, - const size_t * /* dst_origin[3] */, - const size_t * /* region[3] */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueCopyImageToBuffer(cl_command_queue /* command_queue */, - cl_mem /* src_image */, - cl_mem /* dst_buffer */, - const size_t * /* src_origin[3] */, - const size_t * /* region[3] */, - size_t /* dst_offset */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueCopyBufferToImage(cl_command_queue /* command_queue */, - cl_mem /* src_buffer */, - cl_mem /* dst_image */, - size_t /* src_offset */, - const size_t * /* dst_origin[3] */, - const size_t * /* region[3] */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY void * CL_API_CALL -clEnqueueMapBuffer(cl_command_queue /* command_queue */, - cl_mem /* buffer */, - cl_bool /* blocking_map */, - cl_map_flags /* map_flags */, - size_t /* offset */, - size_t /* cb */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY void * CL_API_CALL -clEnqueueMapImage(cl_command_queue /* command_queue */, - cl_mem /* image */, - cl_bool /* blocking_map */, - cl_map_flags /* map_flags */, - const size_t * /* origin[3] */, - const size_t * /* region[3] */, - size_t * /* image_row_pitch */, - size_t * /* image_slice_pitch */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueUnmapMemObject(cl_command_queue /* command_queue */, - cl_mem /* memobj */, - void * /* mapped_ptr */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueNDRangeKernel(cl_command_queue /* command_queue */, - cl_kernel /* kernel */, - cl_uint /* work_dim */, - const size_t * /* global_work_offset */, - const size_t * /* global_work_size */, - const size_t * /* local_work_size */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueTask(cl_command_queue /* command_queue */, - cl_kernel /* kernel */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueNativeKernel(cl_command_queue /* command_queue */, - void (*user_func)(void *), - void * /* args */, - size_t /* cb_args */, - cl_uint /* num_mem_objects */, - const cl_mem * /* mem_list */, - const void ** /* args_mem_loc */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueMarker(cl_command_queue /* command_queue */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueWaitForEvents(cl_command_queue /* command_queue */, - cl_uint /* num_events */, - const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueBarrier(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; - -/* Extension function access - * - * Returns the extension function address for the given function name, - * or NULL if a valid function can not be found. The client must - * check to make sure the address is not NULL, before using or - * calling the returned function address. - */ -extern CL_API_ENTRY void * CL_API_CALL clGetExtensionFunctionAddress(const char * /* func_name */) CL_API_SUFFIX__VERSION_1_0; - -#ifdef __cplusplus -} -#endif - -#endif /* __OPENCL_CL_H */ - diff --git a/KEMField/opencl/1.1/CL/cl.hpp b/KEMField/opencl/1.1/CL/cl.hpp deleted file mode 100644 index 99b86a665..000000000 --- a/KEMField/opencl/1.1/CL/cl.hpp +++ /dev/null @@ -1,4011 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008-2010 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and/or associated documentation files (the - * "Materials"), to deal in the Materials without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Materials, and to - * permit persons to whom the Materials are 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 Materials. - * - * THE MATERIALS ARE 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 - * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. - ******************************************************************************/ - -/*! \file - * - * \brief C++ bindings for OpenCL 1.0 (rev 48) and OpenCL 1.1 (rev 33) - * \author Benedict R. Gaster and Laurent Morichetti - * - * Additions and fixes from Brian Cole, March 3rd 2010. - * - * \version 1.1 - * \date June 2010 - * - * Optional extension support - * - * cl - * cl_ext_device_fission - * #define USE_CL_DEVICE_FISSION - */ - -/*! \mainpage - * \section intro Introduction - * For many large applications C++ is the language of choice and so it seems - * reasonable to define C++ bindings for OpenCL. - * - * - * The interface is contained with a single C++ header file \em cl.hpp and all - * definitions are contained within the namespace \em cl. There is no additional - * requirement to include \em cl.h and to use either the C++ or original C - * bindings it is enough to simply include \em cl.hpp. - * - * The bindings themselves are lightweight and correspond closely to the - * underlying C API. Using the C++ bindings introduces no additional execution - * overhead. - * - * For detail documentation on the bindings see: - * - * The OpenCL C++ Wrapper API 1.1 (revision 04) - * http://www.khronos.org/registry/cl/specs/opencl-cplusplus-1.1.pdf - * - * \section example Example - * - * The following example shows a general use case for the C++ - * bindings, including support for the optional exception feature and - * also the supplied vector and string classes, see following sections for - * decriptions of these features. - * - * \code - * #define __CL_ENABLE_EXCEPTIONS - * - * #if defined(__APPLE__) || defined(__MACOSX) - * #include - * #else - * #include - * #endif - * #include - * #include - * #include - * - * const char * helloStr = "__kernel void " - * "hello(void) " - * "{ " - * " " - * "} "; - * - * int - * main(void) - * { - * cl_int err = CL_SUCCESS; - * try { - * - * std::vector platforms; - * cl::Platform::get(&platforms); - * if (platforms.size() == 0) { - * std::cout << "Platform size 0\n"; - * return -1; - * } - * - * cl_context_properties properties[] = - * { CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms[0])(), 0}; - * cl::Context context(CL_DEVICE_TYPE_CPU, properties); - * - * std::vector devices = context.getInfo(); - * - * cl::Program::Sources source(1, - * std::make_pair(helloStr,strlen(helloStr))); - * cl::Program program_ = cl::Program(context, source); - * program_.build(devices); - * - * cl::Kernel kernel(program_, "hello", &err); - * - * cl::Event event; - * cl::CommandQueue queue(context, devices[0], 0, &err); - * queue.enqueueNDRangeKernel( - * kernel, - * cl::NullRange, - * cl::NDRange(4,4), - * cl::NullRange, - * NULL, - * &event); - * - * event.wait(); - * } - * catch (cl::Error err) { - * std::cerr - * << "ERROR: " - * << err.what() - * << "(" - * << err.err() - * << ")" - * << std::endl; - * } - * - * return EXIT_SUCCESS; - * } - * - * \endcode - * - */ -#ifndef CL_HPP_ -#define CL_HPP_ - -#ifdef _WIN32 -#include -#include -#if defined(USE_DX_INTEROP) -#include -#endif -#endif // _WIN32 - -// -#if defined(USE_CL_DEVICE_FISSION) -#include -#endif - -#if defined(__APPLE__) || defined(__MACOSX) -#include -#include -#else -#include -#include -#endif // !__APPLE__ - -#if !defined(CL_CALLBACK) -#define CL_CALLBACK -#endif //CL_CALLBACK - -#include - -#if !defined(__NO_STD_VECTOR) -#include -#endif - -#if !defined(__NO_STD_STRING) -#include -#endif - -#if defined(linux) || defined(__APPLE__) || defined(__MACOSX) -# include -#endif // linux - -#include - -/*! \namespace cl - * - * \brief The OpenCL C++ bindings are defined within this namespace. - * - */ -namespace cl { - -#define __INIT_CL_EXT_FCN_PTR(name) \ - if(!pfn_##name) { \ - pfn_##name = (PFN_##name) \ - clGetExtensionFunctionAddress(#name); \ - if(!pfn_##name) { \ - } \ - } - -class Program; -class Device; -class Context; -class CommandQueue; -class Memory; - -#if defined(__CL_ENABLE_EXCEPTIONS) -#include -/*! \class Error - * \brief Exception class - */ -class Error : public std::exception -{ -private: - cl_int err_; - const char * errStr_; -public: - /*! Create a new CL error exception for a given error code - * and corresponding message. - */ - Error(cl_int err, const char * errStr = NULL) : err_(err), errStr_(errStr) - {} - - ~Error() throw() {} - - /*! \brief Get error string associated with exception - * - * \return A memory pointer to the error message string. - */ - virtual const char * what() const throw () - { - if (errStr_ == NULL) { - return "empty"; - } - else { - return errStr_; - } - } - - /*! \brief Get error code associated with exception - * - * \return The error code. - */ - const cl_int err(void) const { return err_; } -}; - -#define __ERR_STR(x) #x -#else -#define __ERR_STR(x) NULL -#endif // __CL_ENABLE_EXCEPTIONS - -//! \cond DOXYGEN_DETAIL -#if !defined(__CL_USER_OVERRIDE_ERROR_STRINGS) -#define __GET_DEVICE_INFO_ERR __ERR_STR(clgetDeviceInfo) -#define __GET_PLATFORM_INFO_ERR __ERR_STR(clGetPlatformInfo) -#define __GET_DEVICE_IDS_ERR __ERR_STR(clGetDeviceIDs) -#define __GET_PLATFORM_IDS_ERR __ERR_STR(clGetPlatformIDs) -#define __GET_CONTEXT_INFO_ERR __ERR_STR(clGetContextInfo) -#define __GET_EVENT_INFO_ERR __ERR_STR(clGetEventInfo) -#define __GET_EVENT_PROFILE_INFO_ERR __ERR_STR(clGetEventProfileInfo) -#define __GET_MEM_OBJECT_INFO_ERR __ERR_STR(clGetMemObjectInfo) -#define __GET_IMAGE_INFO_ERR __ERR_STR(clGetImageInfo) -#define __GET_SAMPLER_INFO_ERR __ERR_STR(clGetSamplerInfo) -#define __GET_KERNEL_INFO_ERR __ERR_STR(clGetKernelInfo) -#define __GET_KERNEL_WORK_GROUP_INFO_ERR __ERR_STR(clGetKernelWorkGroupInfo) -#define __GET_PROGRAM_INFO_ERR __ERR_STR(clGetProgramInfo) -#define __GET_PROGRAM_BUILD_INFO_ERR __ERR_STR(clGetProgramBuildInfo) -#define __GET_COMMAND_QUEUE_INFO_ERR __ERR_STR(clGetCommandQueueInfo) - -#define __CREATE_CONTEXT_FROM_TYPE_ERR __ERR_STR(clCreateContextFromType) -#define __GET_SUPPORTED_IMAGE_FORMATS_ERR __ERR_STR(clGetSupportedImageFormats) - -#define __CREATE_BUFFER_ERR __ERR_STR(clCreateBuffer) -#define __CREATE_SUBBUFFER_ERR __ERR_STR(clCreateSubBuffer) -#define __CREATE_GL_BUFFER_ERR __ERR_STR(clCreateFromGLBuffer) -#define __GET_GL_OBJECT_INFO_ERR __ERR_STR(clGetGLObjectInfo) -#define __CREATE_IMAGE2D_ERR __ERR_STR(clCreateImage2D) -#define __CREATE_IMAGE3D_ERR __ERR_STR(clCreateImage3D) -#define __CREATE_SAMPLER_ERR __ERR_STR(clCreateSampler) -#define __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR __ERR_STR(clSetMemObjectDestructorCallback) - -#define __CREATE_USER_EVENT_ERR __ERR_STR(clCreateUserEvent) -#define __SET_USER_EVENT_STATUS_ERR __ERR_STR(clSetUserEventStatus) -#define __SET_EVENT_CALLBACK_ERR __ERR_STR(clSetEventCallback) -#define __WAIT_FOR_EVENTS_ERR __ERR_STR(clWaitForEvents) - -#define __CREATE_KERNEL_ERR __ERR_STR(clCreateKernel) -#define __SET_KERNEL_ARGS_ERR __ERR_STR(clSetKernelArg) -#define __CREATE_PROGRAM_WITH_SOURCE_ERR __ERR_STR(clCreateProgramWithSource) -#define __CREATE_PROGRAM_WITH_BINARY_ERR __ERR_STR(clCreateProgramWithBinary) -#define __BUILD_PROGRAM_ERR __ERR_STR(clBuildProgram) -#define __CREATE_KERNELS_IN_PROGRAM_ERR __ERR_STR(clCreateKernelsInProgram) - -#define __CREATE_COMMAND_QUEUE_ERR __ERR_STR(clCreateCommandQueue) -#define __SET_COMMAND_QUEUE_PROPERTY_ERR __ERR_STR(clSetCommandQueueProperty) -#define __ENQUEUE_READ_BUFFER_ERR __ERR_STR(clEnqueueReadBuffer) -#define __ENQUEUE_READ_BUFFER_RECT_ERR __ERR_STR(clEnqueueReadBufferRect) -#define __ENQUEUE_WRITE_BUFFER_ERR __ERR_STR(clEnqueueWriteBuffer) -#define __ENQUEUE_WRITE_BUFFER_RECT_ERR __ERR_STR(clEnqueueWriteBufferRect) -#define __ENQEUE_COPY_BUFFER_ERR __ERR_STR(clEnqueueCopyBuffer) -#define __ENQEUE_COPY_BUFFER_RECT_ERR __ERR_STR(clEnqueueCopyBufferRect) -#define __ENQUEUE_READ_IMAGE_ERR __ERR_STR(clEnqueueReadImage) -#define __ENQUEUE_WRITE_IMAGE_ERR __ERR_STR(clEnqueueWriteImage) -#define __ENQUEUE_COPY_IMAGE_ERR __ERR_STR(clEnqueueCopyImage) -#define __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR __ERR_STR(clEnqueueCopyImageToBuffer) -#define __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR __ERR_STR(clEnqueueCopyBufferToImage) -#define __ENQUEUE_MAP_BUFFER_ERR __ERR_STR(clEnqueueMapBuffer) -#define __ENQUEUE_MAP_IMAGE_ERR __ERR_STR(clEnqueueMapImage) -#define __ENQUEUE_UNMAP_MEM_OBJECT_ERR __ERR_STR(clEnqueueUnMapMemObject) -#define __ENQUEUE_NDRANGE_KERNEL_ERR __ERR_STR(clEnqueueNDRangeKernel) -#define __ENQUEUE_TASK_ERR __ERR_STR(clEnqueueTask) -#define __ENQUEUE_NATIVE_KERNEL __ERR_STR(clEnqueueNativeKernel) -#define __ENQUEUE_MARKER_ERR __ERR_STR(clEnqueueMarker) -#define __ENQUEUE_WAIT_FOR_EVENTS_ERR __ERR_STR(clEnqueueWaitForEvents) -#define __ENQUEUE_BARRIER_ERR __ERR_STR(clEnqueueBarrier) - -#define __ENQUEUE_ACQUIRE_GL_ERR __ERR_STR(clEnqueueAcquireGLObjects) -#define __ENQUEUE_RELEASE_GL_ERR __ERR_STR(clEnqueueReleaseGLObjects) - -#define __UNLOAD_COMPILER_ERR __ERR_STR(clUnloadCompiler) - -#define __FLUSH_ERR __ERR_STR(clFlush) -#define __FINISH_ERR __ERR_STR(clFinish) - -#define __CREATE_SUB_DEVICES __ERR_STR(clCreateSubDevicesEXT) -#endif // __CL_USER_OVERRIDE_ERROR_STRINGS -//! \endcond - -/*! \class string - * \brief Simple string class, that provides a limited subset of std::string - * functionality but avoids many of the issues that come with that class. - */ -class string -{ -private: - ::size_t size_; - char * str_; -public: - string(void) : size_(0), str_(NULL) - { - } - - string(char * str, ::size_t size) : - size_(size), - str_(NULL) - { - str_ = new char[size_+1]; - if (str_ != NULL) { - memcpy(str_, str, size_ * sizeof(char)); - str_[size_] = '\0'; - } - else { - size_ = 0; - } - } - - string(char * str) : - str_(NULL) - { - size_= ::strlen(str); - str_ = new char[size_ + 1]; - if (str_ != NULL) { - memcpy(str_, str, (size_ + 1) * sizeof(char)); - } - else { - size_ = 0; - } - } - - string& operator=(const string& rhs) - { - if (this == &rhs) { - return *this; - } - - if (rhs.size_ == 0 || rhs.str_ == NULL) { - size_ = 0; - str_ = NULL; - } - else { - size_ = rhs.size_; - str_ = new char[size_ + 1]; - if (str_ != NULL) { - memcpy(str_, rhs.str_, (size_ + 1) * sizeof(char)); - } - else { - size_ = 0; - } - } - - return *this; - } - - string(const string& rhs) - { - *this = rhs; - } - - ~string() - { - if (str_ != NULL) { - delete[] str_; - } - } - - ::size_t size(void) const { return size_; } - ::size_t length(void) const { return size(); } - - const char * c_str(void) const { return (str_) ? str_ : "";} -}; - -#if !defined(__USE_DEV_STRING) && !defined(__NO_STD_STRING) -#include -typedef std::string STRING_CLASS; -#elif !defined(__USE_DEV_STRING) -typedef cl::string STRING_CLASS; -#endif - -#if !defined(__USE_DEV_VECTOR) && !defined(__NO_STD_VECTOR) -#include -#define VECTOR_CLASS std::vector -#elif !defined(__USE_DEV_VECTOR) -#define VECTOR_CLASS cl::vector -#endif - -#if !defined(__MAX_DEFAULT_VECTOR_SIZE) -#define __MAX_DEFAULT_VECTOR_SIZE 10 -#endif - -/*! \class vector - * \brief Fixed sized vector implementation that mirroring - * std::vector functionality. - */ -template -class vector -{ -private: - T data_[N]; - unsigned int size_; - bool empty_; -public: - vector() : - size_(-1), - empty_(true) - {} - - ~vector() {} - - unsigned int size(void) const - { - return size_ + 1; - } - - void clear() - { - size_ = -1; - empty_ = true; - } - - void push_back (const T& x) - { - if (size() < N) { - size_++; - data_[size_] = x; - empty_ = false; - } - } - - void pop_back(void) - { - if (!empty_) { - data_[size_].~T(); - size_--; - if (size_ == -1) { - empty_ = true; - } - } - } - - vector(const vector& vec) : - size_(vec.size_), - empty_(vec.empty_) - { - if (!empty_) { - memcpy(&data_[0], &vec.data_[0], size() * sizeof(T)); - } - } - - vector(unsigned int size, const T& val = T()) : - size_(-1), - empty_(true) - { - for (unsigned int i = 0; i < size; i++) { - push_back(val); - } - } - - vector& operator=(const vector& rhs) - { - if (this == &rhs) { - return *this; - } - - size_ = rhs.size_; - empty_ = rhs.empty_; - - if (!empty_) { - memcpy(&data_[0], &rhs.data_[0], size() * sizeof(T)); - } - - return *this; - } - - bool operator==(vector &vec) - { - if (empty_ && vec.empty_) { - return true; - } - - if (size() != vec.size()) { - return false; - } - - return memcmp(&data_[0], &vec.data_[0], size() * sizeof(T)) == 0 ? true : false; - } - - operator T* () { return data_; } - operator const T* () const { return data_; } - - bool empty (void) const - { - return empty_; - } - - unsigned int max_size (void) const - { - return N; - } - - unsigned int capacity () const - { - return sizeof(T) * N; - } - - T& operator[](int index) - { - return data_[index]; - } - - T operator[](int index) const - { - return data_[index]; - } - - template - void assign(I start, I end) - { - clear(); - while(start < end) { - push_back(*start); - start++; - } - } - - /*! \class iterator - * \brief Iterator class for vectors - */ - class iterator - { - private: - vector vec_; - int index_; - bool initialized_; - public: - iterator(void) : - index_(-1), - initialized_(false) - { - index_ = -1; - initialized_ = false; - } - - ~iterator(void) {} - - static iterator begin(vector &vec) - { - iterator i; - - if (!vec.empty()) { - i.index_ = 0; - } - - i.vec_ = vec; - i.initialized_ = true; - return i; - } - - static iterator end(vector &vec) - { - iterator i; - - if (!vec.empty()) { - i.index_ = vec.size(); - } - i.vec_ = vec; - i.initialized_ = true; - return i; - } - - bool operator==(iterator i) - { - return ((vec_ == i.vec_) && - (index_ == i.index_) && - (initialized_ == i.initialized_)); - } - - bool operator!=(iterator i) - { - return (!(*this==i)); - } - - void operator++() - { - index_++; - } - - void operator++(int x) - { - index_ += x; - } - - void operator--() - { - index_--; - } - - void operator--(int x) - { - index_ -= x; - } - - T operator *() - { - return vec_[index_]; - } - }; - - iterator begin(void) - { - return iterator::begin(*this); - } - - iterator end(void) - { - return iterator::end(*this); - } - - T& front(void) - { - return data_[0]; - } - - T& back(void) - { - return data_[size_]; - } - - const T& front(void) const - { - return data_[0]; - } - - const T& back(void) const - { - return data_[size_]; - } -}; - -/*! - * \brief size_t class used to interface between C++ and - * OpenCL C calls that require arrays of size_t values, who's - * size is known statically. - */ -template -struct size_t : public cl::vector< ::size_t, N> { }; - -namespace detail { - -// GetInfo help struct -template -struct GetInfoHelper -{ - static cl_int - get(Functor f, cl_uint name, T* param) - { - return f(name, sizeof(T), param, NULL); - } -}; - -// Specialized GetInfoHelper for VECTOR_CLASS params -template -struct GetInfoHelper > -{ - static cl_int get(Func f, cl_uint name, VECTOR_CLASS* param) - { - ::size_t required; - cl_int err = f(name, 0, NULL, &required); - if (err != CL_SUCCESS) { - return err; - } - - T* value = (T*) alloca(required); - err = f(name, required, value, NULL); - if (err != CL_SUCCESS) { - return err; - } - - param->assign(&value[0], &value[required/sizeof(T)]); - return CL_SUCCESS; - } -}; - -// Specialized for getInfo -template -struct GetInfoHelper > -{ - static cl_int - get(Func f, cl_uint name, VECTOR_CLASS* param) - { - cl_uint err = f(name, param->size() * sizeof(char *), &(*param)[0], NULL); - if (err != CL_SUCCESS) { - return err; - } - - return CL_SUCCESS; - } -}; - -// Specialized GetInfoHelper for STRING_CLASS params -template -struct GetInfoHelper -{ - static cl_int get(Func f, cl_uint name, STRING_CLASS* param) - { - ::size_t required; - cl_int err = f(name, 0, NULL, &required); - if (err != CL_SUCCESS) { - return err; - } - - char* value = (char*) alloca(required); - err = f(name, required, value, NULL); - if (err != CL_SUCCESS) { - return err; - } - - *param = value; - return CL_SUCCESS; - } -}; - -#define __GET_INFO_HELPER_WITH_RETAIN(CPP_TYPE) \ -namespace detail { \ -template \ -struct GetInfoHelper \ -{ \ - static cl_int get(Func f, cl_uint name, CPP_TYPE* param) \ - { \ - cl_uint err = f(name, sizeof(CPP_TYPE), param, NULL); \ - if (err != CL_SUCCESS) { \ - return err; \ - } \ - \ - return ReferenceHandler::retain((*param)()); \ - } \ -}; \ -} - - -#define __PARAM_NAME_INFO_1_0(F) \ - F(cl_platform_info, CL_PLATFORM_PROFILE, STRING_CLASS) \ - F(cl_platform_info, CL_PLATFORM_VERSION, STRING_CLASS) \ - F(cl_platform_info, CL_PLATFORM_NAME, STRING_CLASS) \ - F(cl_platform_info, CL_PLATFORM_VENDOR, STRING_CLASS) \ - F(cl_platform_info, CL_PLATFORM_EXTENSIONS, STRING_CLASS) \ - \ - F(cl_device_info, CL_DEVICE_TYPE, cl_device_type) \ - F(cl_device_info, CL_DEVICE_VENDOR_ID, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_WORK_GROUP_SIZE, ::size_t) \ - F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_SIZES, VECTOR_CLASS< ::size_t>) \ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, cl_uint) \ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, cl_uint) \ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, cl_uint) \ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, cl_uint) \ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, cl_uint) \ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint) \ - F(cl_device_info, CL_DEVICE_ADDRESS_BITS, cl_bitfield) \ - F(cl_device_info, CL_DEVICE_MAX_READ_IMAGE_ARGS, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_MEM_ALLOC_SIZE, cl_ulong) \ - F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_WIDTH, ::size_t) \ - F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_HEIGHT, ::size_t) \ - F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_WIDTH, ::size_t) \ - F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_HEIGHT, ::size_t) \ - F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_DEPTH, ::size_t) \ - F(cl_device_info, CL_DEVICE_IMAGE_SUPPORT, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_PARAMETER_SIZE, ::size_t) \ - F(cl_device_info, CL_DEVICE_MAX_SAMPLERS, cl_uint) \ - F(cl_device_info, CL_DEVICE_MEM_BASE_ADDR_ALIGN, cl_uint) \ - F(cl_device_info, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, cl_uint) \ - F(cl_device_info, CL_DEVICE_SINGLE_FP_CONFIG, cl_device_fp_config) \ - F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, cl_device_mem_cache_type) \ - F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, cl_uint)\ - F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, cl_ulong) \ - F(cl_device_info, CL_DEVICE_GLOBAL_MEM_SIZE, cl_ulong) \ - F(cl_device_info, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, cl_ulong) \ - F(cl_device_info, CL_DEVICE_MAX_CONSTANT_ARGS, cl_uint) \ - F(cl_device_info, CL_DEVICE_LOCAL_MEM_TYPE, cl_device_local_mem_type) \ - F(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE, cl_ulong) \ - F(cl_device_info, CL_DEVICE_ERROR_CORRECTION_SUPPORT, cl_bool) \ - F(cl_device_info, CL_DEVICE_PROFILING_TIMER_RESOLUTION, ::size_t) \ - F(cl_device_info, CL_DEVICE_ENDIAN_LITTLE, cl_bool) \ - F(cl_device_info, CL_DEVICE_AVAILABLE, cl_bool) \ - F(cl_device_info, CL_DEVICE_COMPILER_AVAILABLE, cl_bool) \ - F(cl_device_info, CL_DEVICE_EXECUTION_CAPABILITIES, cl_device_exec_capabilities) \ - F(cl_device_info, CL_DEVICE_QUEUE_PROPERTIES, cl_command_queue_properties) \ - F(cl_device_info, CL_DEVICE_PLATFORM, cl_platform_id) \ - F(cl_device_info, CL_DEVICE_NAME, STRING_CLASS) \ - F(cl_device_info, CL_DEVICE_VENDOR, STRING_CLASS) \ - F(cl_device_info, CL_DRIVER_VERSION, STRING_CLASS) \ - F(cl_device_info, CL_DEVICE_PROFILE, STRING_CLASS) \ - F(cl_device_info, CL_DEVICE_VERSION, STRING_CLASS) \ - F(cl_device_info, CL_DEVICE_EXTENSIONS, STRING_CLASS) \ - \ - F(cl_context_info, CL_CONTEXT_REFERENCE_COUNT, cl_uint) \ - F(cl_context_info, CL_CONTEXT_DEVICES, VECTOR_CLASS) \ - F(cl_context_info, CL_CONTEXT_PROPERTIES, VECTOR_CLASS) \ - \ - F(cl_event_info, CL_EVENT_COMMAND_QUEUE, cl::CommandQueue) \ - F(cl_event_info, CL_EVENT_COMMAND_TYPE, cl_command_type) \ - F(cl_event_info, CL_EVENT_REFERENCE_COUNT, cl_uint) \ - F(cl_event_info, CL_EVENT_COMMAND_EXECUTION_STATUS, cl_uint) \ - \ - F(cl_profiling_info, CL_PROFILING_COMMAND_QUEUED, cl_ulong) \ - F(cl_profiling_info, CL_PROFILING_COMMAND_SUBMIT, cl_ulong) \ - F(cl_profiling_info, CL_PROFILING_COMMAND_START, cl_ulong) \ - F(cl_profiling_info, CL_PROFILING_COMMAND_END, cl_ulong) \ - \ - F(cl_mem_info, CL_MEM_TYPE, cl_mem_object_type) \ - F(cl_mem_info, CL_MEM_FLAGS, cl_mem_flags) \ - F(cl_mem_info, CL_MEM_SIZE, ::size_t) \ - F(cl_mem_info, CL_MEM_HOST_PTR, void*) \ - F(cl_mem_info, CL_MEM_MAP_COUNT, cl_uint) \ - F(cl_mem_info, CL_MEM_REFERENCE_COUNT, cl_uint) \ - F(cl_mem_info, CL_MEM_CONTEXT, cl::Context) \ - \ - F(cl_image_info, CL_IMAGE_FORMAT, cl_image_format) \ - F(cl_image_info, CL_IMAGE_ELEMENT_SIZE, ::size_t) \ - F(cl_image_info, CL_IMAGE_ROW_PITCH, ::size_t) \ - F(cl_image_info, CL_IMAGE_SLICE_PITCH, ::size_t) \ - F(cl_image_info, CL_IMAGE_WIDTH, ::size_t) \ - F(cl_image_info, CL_IMAGE_HEIGHT, ::size_t) \ - F(cl_image_info, CL_IMAGE_DEPTH, ::size_t) \ - \ - F(cl_sampler_info, CL_SAMPLER_REFERENCE_COUNT, cl_uint) \ - F(cl_sampler_info, CL_SAMPLER_CONTEXT, cl::Context) \ - F(cl_sampler_info, CL_SAMPLER_NORMALIZED_COORDS, cl_addressing_mode) \ - F(cl_sampler_info, CL_SAMPLER_ADDRESSING_MODE, cl_filter_mode) \ - F(cl_sampler_info, CL_SAMPLER_FILTER_MODE, cl_bool) \ - \ - F(cl_program_info, CL_PROGRAM_REFERENCE_COUNT, cl_uint) \ - F(cl_program_info, CL_PROGRAM_CONTEXT, cl::Context) \ - F(cl_program_info, CL_PROGRAM_NUM_DEVICES, cl_uint) \ - F(cl_program_info, CL_PROGRAM_DEVICES, VECTOR_CLASS) \ - F(cl_program_info, CL_PROGRAM_SOURCE, STRING_CLASS) \ - F(cl_program_info, CL_PROGRAM_BINARY_SIZES, VECTOR_CLASS< ::size_t>) \ - F(cl_program_info, CL_PROGRAM_BINARIES, VECTOR_CLASS) \ - \ - F(cl_program_build_info, CL_PROGRAM_BUILD_STATUS, cl_build_status) \ - F(cl_program_build_info, CL_PROGRAM_BUILD_OPTIONS, STRING_CLASS) \ - F(cl_program_build_info, CL_PROGRAM_BUILD_LOG, STRING_CLASS) \ - \ - F(cl_kernel_info, CL_KERNEL_FUNCTION_NAME, STRING_CLASS) \ - F(cl_kernel_info, CL_KERNEL_NUM_ARGS, cl_uint) \ - F(cl_kernel_info, CL_KERNEL_REFERENCE_COUNT, cl_uint) \ - F(cl_kernel_info, CL_KERNEL_CONTEXT, cl::Context) \ - F(cl_kernel_info, CL_KERNEL_PROGRAM, cl::Program) \ - \ - F(cl_kernel_work_group_info, CL_KERNEL_WORK_GROUP_SIZE, ::size_t) \ - F(cl_kernel_work_group_info, CL_KERNEL_COMPILE_WORK_GROUP_SIZE, cl::size_t<3>) \ - F(cl_kernel_work_group_info, CL_KERNEL_LOCAL_MEM_SIZE, cl_ulong) \ - \ - F(cl_command_queue_info, CL_QUEUE_CONTEXT, cl::Context) \ - F(cl_command_queue_info, CL_QUEUE_DEVICE, cl::Device) \ - F(cl_command_queue_info, CL_QUEUE_REFERENCE_COUNT, cl_uint) \ - F(cl_command_queue_info, CL_QUEUE_PROPERTIES, cl_command_queue_properties) - -#if defined(CL_VERSION_1_1) -#define __PARAM_NAME_INFO_1_1(F) \ - F(cl_context_info, CL_CONTEXT_NUM_DEVICES, cl_uint)\ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_INT, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF, cl_uint) \ - F(cl_device_info, CL_DEVICE_DOUBLE_FP_CONFIG, cl_device_fp_config) \ - F(cl_device_info, CL_DEVICE_HALF_FP_CONFIG, cl_device_fp_config) \ - F(cl_device_info, CL_DEVICE_HOST_UNIFIED_MEMORY, cl_bool) \ - \ - F(cl_mem_info, CL_MEM_ASSOCIATED_MEMOBJECT, cl::Memory) \ - F(cl_mem_info, CL_MEM_OFFSET, ::size_t) \ - \ - F(cl_kernel_work_group_info, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, ::size_t) \ - F(cl_kernel_work_group_info, CL_KERNEL_PRIVATE_MEM_SIZE, cl_ulong) \ - \ - F(cl_event_info, CL_EVENT_CONTEXT, cl::Context) -#endif // CL_VERSION_1_1 - -#if defined(USE_CL_DEVICE_FISSION) -#define __PARAM_NAME_DEVICE_FISSION(F) \ - F(cl_device_info, CL_DEVICE_PARENT_DEVICE_EXT, cl_device_id) \ - F(cl_device_info, CL_DEVICE_PARTITION_TYPES_EXT, VECTOR_CLASS) \ - F(cl_device_info, CL_DEVICE_AFFINITY_DOMAINS_EXT, VECTOR_CLASS) \ - F(cl_device_info, CL_DEVICE_REFERENCE_COUNT_EXT , cl_uint) \ - F(cl_device_info, CL_DEVICE_PARTITION_STYLE_EXT, VECTOR_CLASS) -#endif // USE_CL_DEVICE_FISSION - -template -struct param_traits {}; - -#define __DECLARE_PARAM_TRAITS(token, param_name, T) \ -struct token; \ -template<> \ -struct param_traits \ -{ \ - enum { value = param_name }; \ - typedef T param_type; \ -}; - -__PARAM_NAME_INFO_1_0(__DECLARE_PARAM_TRAITS); -#if defined(CL_VERSION_1_1) -__PARAM_NAME_INFO_1_1(__DECLARE_PARAM_TRAITS); -#endif // CL_VERSION_1_1 - -#if defined(USE_CL_DEVICE_FISSION) -__PARAM_NAME_DEVICE_FISSION(__DECLARE_PARAM_TRAITS); -#endif // USE_CL_DEVICE_FISSION - -#undef __DECLARE_PARAM_TRAITS - -// Convenience functions - -template -inline cl_int -getInfo(Func f, cl_uint name, T* param) -{ - return GetInfoHelper::get(f, name, param); -} - -template -struct GetInfoFunctor0 -{ - Func f_; const Arg0& arg0_; - cl_int operator ()( - cl_uint param, ::size_t size, void* value, ::size_t* size_ret) - { return f_(arg0_, param, size, value, size_ret); } -}; - -template -struct GetInfoFunctor1 -{ - Func f_; const Arg0& arg0_; const Arg1& arg1_; - cl_int operator ()( - cl_uint param, ::size_t size, void* value, ::size_t* size_ret) - { return f_(arg0_, arg1_, param, size, value, size_ret); } -}; - -template -inline cl_int -getInfo(Func f, const Arg0& arg0, cl_uint name, T* param) -{ - GetInfoFunctor0 f0 = { f, arg0 }; - return GetInfoHelper, T> - ::get(f0, name, param); -} - -template -inline cl_int -getInfo(Func f, const Arg0& arg0, const Arg1& arg1, cl_uint name, T* param) -{ - GetInfoFunctor1 f0 = { f, arg0, arg1 }; - return GetInfoHelper, T> - ::get(f0, name, param); -} - -template -struct ReferenceHandler -{ }; - -template <> -struct ReferenceHandler -{ - // cl_device_id does not have retain(). - static cl_int retain(cl_device_id) - { return CL_INVALID_DEVICE; } - // cl_device_id does not have release(). - static cl_int release(cl_device_id) - { return CL_INVALID_DEVICE; } -}; - -template <> -struct ReferenceHandler -{ - // cl_platform_id does not have retain(). - static cl_int retain(cl_platform_id) - { return CL_INVALID_PLATFORM; } - // cl_platform_id does not have release(). - static cl_int release(cl_platform_id) - { return CL_INVALID_PLATFORM; } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_context context) - { return ::clRetainContext(context); } - static cl_int release(cl_context context) - { return ::clReleaseContext(context); } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_command_queue queue) - { return ::clRetainCommandQueue(queue); } - static cl_int release(cl_command_queue queue) - { return ::clReleaseCommandQueue(queue); } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_mem memory) - { return ::clRetainMemObject(memory); } - static cl_int release(cl_mem memory) - { return ::clReleaseMemObject(memory); } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_sampler sampler) - { return ::clRetainSampler(sampler); } - static cl_int release(cl_sampler sampler) - { return ::clReleaseSampler(sampler); } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_program program) - { return ::clRetainProgram(program); } - static cl_int release(cl_program program) - { return ::clReleaseProgram(program); } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_kernel kernel) - { return ::clRetainKernel(kernel); } - static cl_int release(cl_kernel kernel) - { return ::clReleaseKernel(kernel); } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_event event) - { return ::clRetainEvent(event); } - static cl_int release(cl_event event) - { return ::clReleaseEvent(event); } -}; - -template -class Wrapper -{ -public: - typedef T cl_type; - -protected: - cl_type object_; - -public: - Wrapper() : object_(NULL) { } - - ~Wrapper() - { - if (object_ != NULL) { release(); } - } - - Wrapper(const Wrapper& rhs) - { - object_ = rhs.object_; - if (object_ != NULL) { retain(); } - } - - Wrapper& operator = (const Wrapper& rhs) - { - if (object_ != NULL) { release(); } - object_ = rhs.object_; - if (object_ != NULL) { retain(); } - return *this; - } - - cl_type operator ()() const { return object_; } - - cl_type& operator ()() { return object_; } - -protected: - - cl_int retain() const - { - return ReferenceHandler::retain(object_); - } - - cl_int release() const - { - return ReferenceHandler::release(object_); - } -}; - -#if defined(__CL_ENABLE_EXCEPTIONS) -static inline cl_int errHandler ( - cl_int err, - const char * errStr = NULL) throw(Error) -{ - if (err != CL_SUCCESS) { - throw Error(err, errStr); - } - return err; -} -#else -static inline cl_int errHandler (cl_int err, const char * errStr = NULL) -{ - return err; -} -#endif // __CL_ENABLE_EXCEPTIONS - -} // namespace detail -//! \endcond - -/*! \stuct ImageFormat - * \brief ImageFormat interface fro cl_image_format. - */ -struct ImageFormat : public cl_image_format -{ - ImageFormat(){} - - ImageFormat(cl_channel_order order, cl_channel_type type) - { - image_channel_order = order; - image_channel_data_type = type; - } - - ImageFormat& operator = (const ImageFormat& rhs) - { - if (this != &rhs) { - this->image_channel_data_type = rhs.image_channel_data_type; - this->image_channel_order = rhs.image_channel_order; - } - return *this; - } -}; - -/*! \class Device - * \brief Device interface for cl_device_id. - */ -class Device : public detail::Wrapper -{ -public: - Device(cl_device_id device) { object_ = device; } - - Device() : detail::Wrapper() { } - - Device(const Device& device) : detail::Wrapper(device) { } - - Device& operator = (const Device& rhs) - { - if (this != &rhs) { - detail::Wrapper::operator=(rhs); - } - return *this; - } - - template - cl_int getInfo(cl_device_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetDeviceInfo, object_, name, param), - __GET_DEVICE_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_device_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - -#if defined(USE_CL_DEVICE_FISSION) - cl_int createSubDevices( - const cl_device_partition_property_ext * properties, - VECTOR_CLASS* devices) - { - typedef CL_API_ENTRY cl_int - ( CL_API_CALL * PFN_clCreateSubDevicesEXT)( - cl_device_id /*in_device*/, - const cl_device_partition_property_ext * /* properties */, - cl_uint /*num_entries*/, - cl_device_id * /*out_devices*/, - cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1; - - static PFN_clCreateSubDevicesEXT pfn_clCreateSubDevicesEXT = NULL; - __INIT_CL_EXT_FCN_PTR(clCreateSubDevicesEXT); - - cl_uint n = 0; - cl_int err = pfn_clCreateSubDevicesEXT(object_, properties, 0, NULL, &n); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __CREATE_SUB_DEVICES); - } - - cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id)); - err = pfn_clCreateSubDevicesEXT(object_, properties, n, ids, NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __CREATE_SUB_DEVICES); - } - - devices->assign(&ids[0], &ids[n]); - return CL_SUCCESS; - } -#endif -}; - -/*! \class Platform - * \brief Platform interface. - */ -class Platform : public detail::Wrapper -{ -public: - static const Platform null(); - - Platform(cl_platform_id platform) { object_ = platform; } - - Platform() : detail::Wrapper() { } - - Platform(const Platform& platform) : detail::Wrapper(platform) { } - - Platform& operator = (const Platform& rhs) - { - if (this != &rhs) { - detail::Wrapper::operator=(rhs); - } - return *this; - } - - cl_int getInfo(cl_platform_info name, STRING_CLASS* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetPlatformInfo, object_, name, param), - __GET_PLATFORM_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_platform_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - cl_int getDevices( - cl_device_type type, - VECTOR_CLASS* devices) const - { - cl_uint n = 0; - cl_int err = ::clGetDeviceIDs(object_, type, 0, NULL, &n); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_DEVICE_IDS_ERR); - } - - cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id)); - err = ::clGetDeviceIDs(object_, type, n, ids, NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_DEVICE_IDS_ERR); - } - - devices->assign(&ids[0], &ids[n]); - return CL_SUCCESS; - } - -#if defined(USE_DX_INTEROP) - /*! \brief Get the list of available D3D10 devices. - * - * \param d3d_device_source. - * - * \param d3d_object. - * - * \param d3d_device_set. - * - * \param devices returns a vector of OpenCL D3D10 devices found. The cl::Device - * values returned in devices can be used to identify a specific OpenCL - * device. If \a devices argument is NULL, this argument is ignored. - * - * \return One of the following values: - * - CL_SUCCESS if the function is executed successfully. - * - * The application can query specific capabilities of the OpenCL device(s) - * returned by cl::getDevices. This can be used by the application to - * determine which device(s) to use. - * - * \note In the case that exceptions are enabled and a return value - * other than CL_SUCCESS is generated, then cl::Error exception is - * generated. - */ - cl_int getDevices( - cl_d3d10_device_source_khr d3d_device_source, - void * d3d_object, - cl_d3d10_device_set_khr d3d_device_set, - VECTOR_CLASS* devices) const - { - typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clGetDeviceIDsFromD3D10KHR)( - cl_platform_id platform, - cl_d3d10_device_source_khr d3d_device_source, - void * d3d_object, - cl_d3d10_device_set_khr d3d_device_set, - cl_uint num_entries, - cl_device_id * devices, - cl_uint* num_devices); - - static PFN_clGetDeviceIDsFromD3D10KHR pfn_clGetDeviceIDsFromD3D10KHR = NULL; - __INIT_CL_EXT_FCN_PTR(clGetDeviceIDsFromD3D10KHR); - - cl_uint n = 0; - cl_int err = pfn_clGetDeviceIDsFromD3D10KHR( - object_, - d3d_device_source, - d3d_object, - d3d_device_set, - 0, - NULL, - &n); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_DEVICE_IDS_ERR); - } - - cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id)); - err = pfn_clGetDeviceIDsFromD3D10KHR( - object_, - d3d_device_source, - d3d_object, - d3d_device_set, - n, - ids, - NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_DEVICE_IDS_ERR); - } - - devices->assign(&ids[0], &ids[n]); - return CL_SUCCESS; - } -#endif - - static cl_int get( - VECTOR_CLASS* platforms) - { - cl_uint n = 0; - cl_int err = ::clGetPlatformIDs(0, NULL, &n); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_PLATFORM_IDS_ERR); - } - - cl_platform_id* ids = (cl_platform_id*) alloca( - n * sizeof(cl_platform_id)); - err = ::clGetPlatformIDs(n, ids, NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_PLATFORM_IDS_ERR); - } - - platforms->assign(&ids[0], &ids[n]); - return CL_SUCCESS; - } -}; - -static inline cl_int -UnloadCompiler() -{ - return ::clUnloadCompiler(); -} - -class Context : public detail::Wrapper -{ -public: - Context( - const VECTOR_CLASS& devices, - cl_context_properties* properties = NULL, - void (CL_CALLBACK * notifyFptr)( - const char *, - const void *, - ::size_t, - void *) = NULL, - void* data = NULL, - cl_int* err = NULL) - { - cl_int error; - object_ = ::clCreateContext( - properties, (cl_uint) devices.size(), - (cl_device_id*) &devices.front(), - notifyFptr, data, &error); - - detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR); - if (err != NULL) { - *err = error; - } - } - - Context( - cl_device_type type, - cl_context_properties* properties = NULL, - void (CL_CALLBACK * notifyFptr)( - const char *, - const void *, - ::size_t, - void *) = NULL, - void* data = NULL, - cl_int* err = NULL) - { - cl_int error; - object_ = ::clCreateContextFromType( - properties, type, notifyFptr, data, &error); - - detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR); - if (err != NULL) { - *err = error; - } - } - - Context() : detail::Wrapper() { } - - Context(const Context& context) : detail::Wrapper(context) { } - - Context& operator = (const Context& rhs) - { - if (this != &rhs) { - detail::Wrapper::operator=(rhs); - } - return *this; - } - - template - cl_int getInfo(cl_context_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetContextInfo, object_, name, param), - __GET_CONTEXT_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_context_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - cl_int getSupportedImageFormats( - cl_mem_flags flags, - cl_mem_object_type type, - VECTOR_CLASS* formats) const - { - cl_uint numEntries; - cl_int err = ::clGetSupportedImageFormats( - object_, - flags, - type, - 0, - NULL, - &numEntries); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR); - } - - ImageFormat* value = (ImageFormat*) - alloca(numEntries * sizeof(ImageFormat)); - err = ::clGetSupportedImageFormats( - object_, - flags, - type, - numEntries, - (cl_image_format*) value, - NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR); - } - - formats->assign(&value[0], &value[numEntries]); - return CL_SUCCESS; - } -}; - -__GET_INFO_HELPER_WITH_RETAIN(cl::Context) - -/*! \class Event - * \brief Event interface for cl_event. - */ -class Event : public detail::Wrapper -{ -public: - Event() : detail::Wrapper() { } - - Event(const Event& event) : detail::Wrapper(event) { } - - Event& operator = (const Event& rhs) - { - if (this != &rhs) { - detail::Wrapper::operator=(rhs); - } - return *this; - } - - template - cl_int getInfo(cl_event_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetEventInfo, object_, name, param), - __GET_EVENT_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_event_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - template - cl_int getProfilingInfo(cl_profiling_info name, T* param) const - { - return detail::errHandler(detail::getInfo( - &::clGetEventProfilingInfo, object_, name, param), - __GET_EVENT_PROFILE_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getProfilingInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_profiling_info, name>::param_type param; - cl_int result = getProfilingInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - cl_int wait() const - { - return detail::errHandler( - ::clWaitForEvents(1, &object_), - __WAIT_FOR_EVENTS_ERR); - } - -#if defined(CL_VERSION_1_1) - cl_int setCallback( - cl_int type, - void (CL_CALLBACK * pfn_notify)(cl_event, cl_int, void *), - void * user_data = NULL) - { - return detail::errHandler( - ::clSetEventCallback( - object_, - type, - pfn_notify, - user_data), - __SET_EVENT_CALLBACK_ERR); - } -#endif - - static cl_int - waitForEvents(const VECTOR_CLASS& events) - { - return detail::errHandler( - ::clWaitForEvents( - (cl_uint) events.size(), (cl_event*)&events.front()), - __WAIT_FOR_EVENTS_ERR); - } -}; - -__GET_INFO_HELPER_WITH_RETAIN(cl::Event) - -#if defined(CL_VERSION_1_1) -/*! \class UserEvent - * \brief User event interface for cl_event. - */ -class UserEvent : public Event -{ -public: - UserEvent( - const Context& context, - cl_int * err = NULL) - { - cl_int error; - object_ = ::clCreateUserEvent( - context(), - &error); - - detail::errHandler(error, __CREATE_USER_EVENT_ERR); - if (err != NULL) { - *err = error; - } - } - - UserEvent() : Event() { } - - UserEvent(const UserEvent& event) : Event(event) { } - - UserEvent& operator = (const UserEvent& rhs) - { - if (this != &rhs) { - Event::operator=(rhs); - } - return *this; - } - - cl_int setStatus(cl_int status) - { - return detail::errHandler( - ::clSetUserEventStatus(object_,status), - __SET_USER_EVENT_STATUS_ERR); - } -}; -#endif - -inline static cl_int -WaitForEvents(const VECTOR_CLASS& events) -{ - return detail::errHandler( - ::clWaitForEvents( - (cl_uint) events.size(), (cl_event*)&events.front()), - __WAIT_FOR_EVENTS_ERR); -} - -/*! \class Memory - * \brief Memory interface for cl_mem. - */ -class Memory : public detail::Wrapper -{ -public: - Memory() : detail::Wrapper() { } - - Memory(const Memory& memory) : detail::Wrapper(memory) { } - - Memory& operator = (const Memory& rhs) - { - if (this != &rhs) { - detail::Wrapper::operator=(rhs); - } - return *this; - } - - template - cl_int getInfo(cl_mem_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetMemObjectInfo, object_, name, param), - __GET_MEM_OBJECT_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_mem_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - -#if defined(CL_VERSION_1_1) - cl_int setDestructorCallback( - void (CL_CALLBACK * pfn_notify)(cl_mem, void *), - void * user_data = NULL) - { - return detail::errHandler( - ::clSetMemObjectDestructorCallback( - object_, - pfn_notify, - user_data), - __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR); - } -#endif - -}; - -__GET_INFO_HELPER_WITH_RETAIN(cl::Memory) - -/*! \class Buffer - * \brief Memory buffer interface. - */ -class Buffer : public Memory -{ -public: - Buffer( - const Context& context, - cl_mem_flags flags, - ::size_t size, - void* host_ptr = NULL, - cl_int* err = NULL) - { - cl_int error; - object_ = ::clCreateBuffer(context(), flags, size, host_ptr, &error); - - detail::errHandler(error, __CREATE_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } - - Buffer() : Memory() { } - - Buffer(const Buffer& buffer) : Memory(buffer) { } - - Buffer& operator = (const Buffer& rhs) - { - if (this != &rhs) { - Memory::operator=(rhs); - } - return *this; - } - -#if defined(CL_VERSION_1_1) - Buffer createSubBuffer( - cl_mem_flags flags, - cl_buffer_create_type buffer_create_type, - const void * buffer_create_info, - cl_int * err = NULL) - { - Buffer result; - cl_int error; - result.object_ = ::clCreateSubBuffer( - object_, - flags, - buffer_create_type, - buffer_create_info, - &error); - - detail::errHandler(error, __CREATE_SUBBUFFER_ERR); - if (err != NULL) { - *err = error; - } - - return result; - } -#endif -}; - -#if defined (USE_DX_INTEROP) -class BufferD3D10 : public Buffer -{ -public: - typedef CL_API_ENTRY cl_mem (CL_API_CALL *PFN_clCreateFromD3D10BufferKHR)( - cl_context context, cl_mem_flags flags, ID3D10Buffer* buffer, - cl_int* errcode_ret); - - BufferD3D10( - const Context& context, - cl_mem_flags flags, - ID3D10Buffer* bufobj, - cl_int * err = NULL) - { - static PFN_clCreateFromD3D10BufferKHR pfn_clCreateFromD3D10BufferKHR = NULL; - __INIT_CL_EXT_FCN_PTR(clCreateFromD3D10BufferKHR); - - cl_int error; - object_ = pfn_clCreateFromD3D10BufferKHR( - context(), - flags, - bufobj, - &error); - - detail::errHandler(error, __CREATE_GL_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } - - BufferD3D10() : Buffer() { } - - BufferD3D10(const BufferD3D10& buffer) : Buffer(buffer) { } - - BufferD3D10& operator = (const BufferD3D10& rhs) - { - if (this != &rhs) { - Buffer::operator=(rhs); - } - return *this; - } -}; -#endif - -/*! \class BufferGL - * \brief Memory buffer interface for GL interop. - */ -class BufferGL : public Buffer -{ -public: - BufferGL( - const Context& context, - cl_mem_flags flags, - GLuint bufobj, - cl_int * err = NULL) - { - cl_int error; - object_ = ::clCreateFromGLBuffer( - context(), - flags, - bufobj, - &error); - - detail::errHandler(error, __CREATE_GL_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } - - BufferGL() : Buffer() { } - - BufferGL(const BufferGL& buffer) : Buffer(buffer) { } - - BufferGL& operator = (const BufferGL& rhs) - { - if (this != &rhs) { - Buffer::operator=(rhs); - } - return *this; - } - - cl_int getObjectInfo( - cl_gl_object_type *type, - GLuint * gl_object_name) - { - return detail::errHandler( - ::clGetGLObjectInfo(object_,type,gl_object_name), - __GET_GL_OBJECT_INFO_ERR); - } -}; - -/*! \class BufferRenderGL - * \brief Memory buffer interface for GL interop with renderbuffer. - */ -class BufferRenderGL : public Buffer -{ -public: - BufferRenderGL( - const Context& context, - cl_mem_flags flags, - GLuint bufobj, - cl_int * err = NULL) - { - cl_int error; - object_ = ::clCreateFromGLRenderbuffer( - context(), - flags, - bufobj, - &error); - - detail::errHandler(error, __CREATE_GL_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } - - BufferRenderGL() : Buffer() { } - - BufferRenderGL(const BufferGL& buffer) : Buffer(buffer) { } - - BufferRenderGL& operator = (const BufferRenderGL& rhs) - { - if (this != &rhs) { - Buffer::operator=(rhs); - } - return *this; - } - - cl_int getObjectInfo( - cl_gl_object_type *type, - GLuint * gl_object_name) - { - return detail::errHandler( - ::clGetGLObjectInfo(object_,type,gl_object_name), - __GET_GL_OBJECT_INFO_ERR); - } -}; - -/*! \class Image - * \brief Base class interface for all images. - */ -class Image : public Memory -{ -protected: - Image() : Memory() { } - - Image(const Image& image) : Memory(image) { } - - Image& operator = (const Image& rhs) - { - if (this != &rhs) { - Memory::operator=(rhs); - } - return *this; - } -public: - template - cl_int getImageInfo(cl_image_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetImageInfo, object_, name, param), - __GET_IMAGE_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getImageInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_image_info, name>::param_type param; - cl_int result = getImageInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } -}; - -/*! \class Image2D - * \brief Image interface for 2D images. - */ -class Image2D : public Image -{ -public: - Image2D( - const Context& context, - cl_mem_flags flags, - ImageFormat format, - ::size_t width, - ::size_t height, - ::size_t row_pitch = 0, - void* host_ptr = NULL, - cl_int* err = NULL) - { - cl_int error; - object_ = ::clCreateImage2D( - context(), flags,&format, width, height, row_pitch, host_ptr, &error); - - detail::errHandler(error, __CREATE_IMAGE2D_ERR); - if (err != NULL) { - *err = error; - } - } - - Image2D() { } - - Image2D(const Image2D& image2D) : Image(image2D) { } - - Image2D& operator = (const Image2D& rhs) - { - if (this != &rhs) { - Image::operator=(rhs); - } - return *this; - } -}; - -/*! \class Image2DGL - * \brief 2D image interface for GL interop. - */ -class Image2DGL : public Image2D -{ -public: - Image2DGL( - const Context& context, - cl_mem_flags flags, - GLenum target, - GLint miplevel, - GLuint texobj, - cl_int * err = NULL) - { - cl_int error; - object_ = ::clCreateFromGLTexture2D( - context(), - flags, - target, - miplevel, - texobj, - &error); - - detail::errHandler(error, __CREATE_GL_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } - - Image2DGL() : Image2D() { } - - Image2DGL(const Image2DGL& image) : Image2D(image) { } - - Image2DGL& operator = (const Image2DGL& rhs) - { - if (this != &rhs) { - Image2D::operator=(rhs); - } - return *this; - } -}; - -/*! \class Image3D - * \brief Image interface for 3D images. - */ -class Image3D : public Image -{ -public: - Image3D( - const Context& context, - cl_mem_flags flags, - ImageFormat format, - ::size_t width, - ::size_t height, - ::size_t depth, - ::size_t row_pitch = 0, - ::size_t slice_pitch = 0, - void* host_ptr = NULL, - cl_int* err = NULL) - { - cl_int error; - object_ = ::clCreateImage3D( - context(), flags, &format, width, height, depth, row_pitch, - slice_pitch, host_ptr, &error); - - detail::errHandler(error, __CREATE_IMAGE3D_ERR); - if (err != NULL) { - *err = error; - } - } - - Image3D() { } - - Image3D(const Image3D& image3D) : Image(image3D) { } - - Image3D& operator = (const Image3D& rhs) - { - if (this != &rhs) { - Image::operator=(rhs); - } - return *this; - } -}; - -/*! \class Image2DGL - * \brief 2D image interface for GL interop. - */ -class Image3DGL : public Image3D -{ -public: - Image3DGL( - const Context& context, - cl_mem_flags flags, - GLenum target, - GLint miplevel, - GLuint texobj, - cl_int * err = NULL) - { - cl_int error; - object_ = ::clCreateFromGLTexture3D( - context(), - flags, - target, - miplevel, - texobj, - &error); - - detail::errHandler(error, __CREATE_GL_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } - - Image3DGL() : Image3D() { } - - Image3DGL(const Image3DGL& image) : Image3D(image) { } - - Image3DGL& operator = (const Image3DGL& rhs) - { - if (this != &rhs) { - Image3D::operator=(rhs); - } - return *this; - } -}; - -/*! \class Sampler - * \brief Sampler interface for cl_sampler. - */ -class Sampler : public detail::Wrapper -{ -public: - Sampler() { } - - Sampler( - const Context& context, - cl_bool normalized_coords, - cl_addressing_mode addressing_mode, - cl_filter_mode filter_mode, - cl_int* err = NULL) - { - cl_int error; - object_ = ::clCreateSampler( - context(), - normalized_coords, - addressing_mode, - filter_mode, - &error); - - detail::errHandler(error, __CREATE_SAMPLER_ERR); - if (err != NULL) { - *err = error; - } - } - - Sampler(const Sampler& sampler) : detail::Wrapper(sampler) { } - - Sampler& operator = (const Sampler& rhs) - { - if (this != &rhs) { - detail::Wrapper::operator=(rhs); - } - return *this; - } - - template - cl_int getInfo(cl_sampler_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetSamplerInfo, object_, name, param), - __GET_SAMPLER_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_sampler_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } -}; - -__GET_INFO_HELPER_WITH_RETAIN(cl::Sampler) - -class Program; -class CommandQueue; -class Kernel; - -/*! \class NDRange - * \brief NDRange interface - */ -class NDRange -{ -private: - size_t<3> sizes_; - cl_uint dimensions_; - -public: - NDRange() - : dimensions_(0) - { } - - NDRange(::size_t size0) - : dimensions_(1) - { - sizes_.push_back(size0); - } - - NDRange(::size_t size0, ::size_t size1) - : dimensions_(2) - { - sizes_.push_back(size0); - sizes_.push_back(size1); - } - - NDRange(::size_t size0, ::size_t size1, ::size_t size2) - : dimensions_(3) - { - sizes_.push_back(size0); - sizes_.push_back(size1); - sizes_.push_back(size2); - } - - operator const ::size_t*() const { return (const ::size_t*) sizes_; } - ::size_t dimensions() const { return dimensions_; } -}; - -static const NDRange NullRange; - -/*! - * \struct LocalSpaceArg - * \brief Local address raper for use with Kernel::setArg - */ -struct LocalSpaceArg -{ - ::size_t size_; -}; - -namespace detail { - -template -struct KernelArgumentHandler -{ - static ::size_t size(const T&) { return sizeof(T); } - static T* ptr(T& value) { return &value; } -}; - -template <> -struct KernelArgumentHandler -{ - static ::size_t size(const LocalSpaceArg& value) { return value.size_; } - static void* ptr(LocalSpaceArg&) { return NULL; } -}; - -} -//! \endcond - -inline LocalSpaceArg -__local(::size_t size) -{ - LocalSpaceArg ret = { size }; - return ret; -} - -class KernelFunctor; - -/*! \class Kernel - * \brief Kernel interface that implements cl_kernel - */ -class Kernel : public detail::Wrapper -{ -public: - inline Kernel(const Program& program, const char* name, cl_int* err = NULL); - - Kernel() { } - - Kernel(const Kernel& kernel) : detail::Wrapper(kernel) { } - - Kernel& operator = (const Kernel& rhs) - { - if (this != &rhs) { - detail::Wrapper::operator=(rhs); - } - return *this; - } - - template - cl_int getInfo(cl_kernel_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetKernelInfo, object_, name, param), - __GET_KERNEL_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_kernel_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - template - cl_int getWorkGroupInfo( - const Device& device, cl_kernel_work_group_info name, T* param) const - { - return detail::errHandler( - detail::getInfo( - &::clGetKernelWorkGroupInfo, object_, device(), name, param), - __GET_KERNEL_WORK_GROUP_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getWorkGroupInfo(const Device& device, cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_kernel_work_group_info, name>::param_type param; - cl_int result = getWorkGroupInfo(device, name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - template - cl_int setArg(cl_uint index, T value) - { - return detail::errHandler( - ::clSetKernelArg( - object_, - index, - detail::KernelArgumentHandler::size(value), - detail::KernelArgumentHandler::ptr(value)), - __SET_KERNEL_ARGS_ERR); - } - - cl_int setArg(cl_uint index, ::size_t size, void* argPtr) - { - return detail::errHandler( - ::clSetKernelArg(object_, index, size, argPtr), - __SET_KERNEL_ARGS_ERR); - } - - KernelFunctor bind( - const CommandQueue& queue, - const NDRange& offset, - const NDRange& global, - const NDRange& local); - - KernelFunctor bind( - const CommandQueue& queue, - const NDRange& global, - const NDRange& local); -}; - -__GET_INFO_HELPER_WITH_RETAIN(cl::Kernel) - -/*! \class Program - * \brief Program interface that implements cl_program. - */ -class Program : public detail::Wrapper -{ -public: - typedef VECTOR_CLASS > Binaries; - typedef VECTOR_CLASS > Sources; - - Program( - const Context& context, - const Sources& sources, - cl_int* err = NULL) - { - cl_int error; - - const ::size_t n = (::size_t)sources.size(); - ::size_t* lengths = (::size_t*) alloca(n * sizeof(::size_t)); - const char** strings = (const char**) alloca(n * sizeof(const char*)); - - for (::size_t i = 0; i < n; ++i) { - strings[i] = sources[(int)i].first; - lengths[i] = sources[(int)i].second; - } - - object_ = ::clCreateProgramWithSource( - context(), (cl_uint)n, strings, lengths, &error); - - detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR); - if (err != NULL) { - *err = error; - } - } - - Program( - const Context& context, - const VECTOR_CLASS& devices, - const Binaries& binaries, - VECTOR_CLASS* binaryStatus = NULL, - cl_int* err = NULL) - { - cl_int error; - const ::size_t n = binaries.size(); - ::size_t* lengths = (::size_t*) alloca(n * sizeof(::size_t)); - const unsigned char** images = (const unsigned char**) alloca(n * sizeof(const void*)); - - for (::size_t i = 0; i < n; ++i) { - images[i] = (const unsigned char*)binaries[(int)i].first; - lengths[i] = binaries[(int)i].second; - } - - object_ = ::clCreateProgramWithBinary( - context(), (cl_uint) devices.size(), - (cl_device_id*)&devices.front(), - lengths, images, binaryStatus != NULL - ? (cl_int*) &binaryStatus->front() - : NULL, &error); - - detail::errHandler(error, __CREATE_PROGRAM_WITH_BINARY_ERR); - if (err != NULL) { - *err = error; - } - } - - Program() { } - - Program(const Program& program) : detail::Wrapper(program) { } - - Program& operator = (const Program& rhs) - { - if (this != &rhs) { - detail::Wrapper::operator=(rhs); - } - return *this; - } - - cl_int build( - const VECTOR_CLASS& devices, - const char* options = NULL, - void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL, - void* data = NULL) const - { - return detail::errHandler( - ::clBuildProgram( - object_, - (cl_uint) - devices.size(), - (cl_device_id*)&devices.front(), - options, - notifyFptr, - data), - __BUILD_PROGRAM_ERR); - } - - template - cl_int getInfo(cl_program_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetProgramInfo, object_, name, param), - __GET_PROGRAM_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_program_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - template - cl_int getBuildInfo( - const Device& device, cl_program_build_info name, T* param) const - { - return detail::errHandler( - detail::getInfo( - &::clGetProgramBuildInfo, object_, device(), name, param), - __GET_PROGRAM_BUILD_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getBuildInfo(const Device& device, cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_program_build_info, name>::param_type param; - cl_int result = getBuildInfo(device, name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - cl_int createKernels(VECTOR_CLASS* kernels) - { - cl_uint numKernels; - cl_int err = ::clCreateKernelsInProgram(object_, 0, NULL, &numKernels); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR); - } - - Kernel* value = (Kernel*) alloca(numKernels * sizeof(Kernel)); - err = ::clCreateKernelsInProgram( - object_, numKernels, (cl_kernel*) value, NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR); - } - - kernels->assign(&value[0], &value[numKernels]); - return CL_SUCCESS; - } -}; - -__GET_INFO_HELPER_WITH_RETAIN(cl::Program) - -inline Kernel::Kernel(const Program& program, const char* name, cl_int* err) -{ - cl_int error; - - object_ = ::clCreateKernel(program(), name, &error); - detail::errHandler(error, __CREATE_KERNEL_ERR); - - if (err != NULL) { - *err = error; - } - -} - -/*! \class CommandQueue - * \brief CommandQueue interface for cl_command_queue. - */ -class CommandQueue : public detail::Wrapper -{ -public: - CommandQueue( - const Context& context, - const Device& device, - cl_command_queue_properties properties = 0, - cl_int* err = NULL) - { - cl_int error; - object_ = ::clCreateCommandQueue( - context(), device(), properties, &error); - - detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); - if (err != NULL) { - *err = error; - } - } - - CommandQueue() { } - - CommandQueue(const CommandQueue& commandQueue) : detail::Wrapper(commandQueue) { } - - CommandQueue& operator = (const CommandQueue& rhs) - { - if (this != &rhs) { - detail::Wrapper::operator=(rhs); - } - return *this; - } - - template - cl_int getInfo(cl_command_queue_info name, T* param) const - { - return detail::errHandler( - detail::getInfo( - &::clGetCommandQueueInfo, object_, name, param), - __GET_COMMAND_QUEUE_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_command_queue_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - cl_int enqueueReadBuffer( - const Buffer& buffer, - cl_bool blocking, - ::size_t offset, - ::size_t size, - void* ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueReadBuffer( - object_, buffer(), blocking, offset, size, - ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_READ_BUFFER_ERR); - } - - cl_int enqueueWriteBuffer( - const Buffer& buffer, - cl_bool blocking, - ::size_t offset, - ::size_t size, - const void* ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueWriteBuffer( - object_, buffer(), blocking, offset, size, - ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_WRITE_BUFFER_ERR); - } - - cl_int enqueueCopyBuffer( - const Buffer& src, - const Buffer& dst, - ::size_t src_offset, - ::size_t dst_offset, - ::size_t size, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueCopyBuffer( - object_, src(), dst(), src_offset, dst_offset, size, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQEUE_COPY_BUFFER_ERR); - } - -#if defined(CL_VERSION_1_1) - cl_int enqueueReadBufferRect( - const Buffer& buffer, - cl_bool blocking, - const size_t<3>& buffer_offset, - const size_t<3>& host_offset, - const size_t<3>& region, - ::size_t buffer_row_pitch, - ::size_t buffer_slice_pitch, - ::size_t host_row_pitch, - ::size_t host_slice_pitch, - void *ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueReadBufferRect( - object_, - buffer(), - blocking, - (const ::size_t *)buffer_offset, - (const ::size_t *)host_offset, - (const ::size_t *)region, - buffer_row_pitch, - buffer_slice_pitch, - host_row_pitch, - host_slice_pitch, - ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_READ_BUFFER_RECT_ERR); - } - - - cl_int enqueueWriteBufferRect( - const Buffer& buffer, - cl_bool blocking, - const size_t<3>& buffer_offset, - const size_t<3>& host_offset, - const size_t<3>& region, - ::size_t buffer_row_pitch, - ::size_t buffer_slice_pitch, - ::size_t host_row_pitch, - ::size_t host_slice_pitch, - void *ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueWriteBufferRect( - object_, - buffer(), - blocking, - (const ::size_t *)buffer_offset, - (const ::size_t *)host_offset, - (const ::size_t *)region, - buffer_row_pitch, - buffer_slice_pitch, - host_row_pitch, - host_slice_pitch, - ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_WRITE_BUFFER_RECT_ERR); - } - - cl_int enqueueCopyBufferRect( - const Buffer& src, - const Buffer& dst, - const size_t<3>& src_origin, - const size_t<3>& dst_origin, - const size_t<3>& region, - ::size_t src_row_pitch, - ::size_t src_slice_pitch, - ::size_t dst_row_pitch, - ::size_t dst_slice_pitch, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueCopyBufferRect( - object_, - src(), - dst(), - (const ::size_t *)src_origin, - (const ::size_t *)dst_origin, - (const ::size_t *)region, - src_row_pitch, - src_slice_pitch, - dst_row_pitch, - dst_slice_pitch, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQEUE_COPY_BUFFER_RECT_ERR); - } -#endif - - cl_int enqueueReadImage( - const Image& image, - cl_bool blocking, - const size_t<3>& origin, - const size_t<3>& region, - ::size_t row_pitch, - ::size_t slice_pitch, - void* ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueReadImage( - object_, image(), blocking, (const ::size_t *) origin, - (const ::size_t *) region, row_pitch, slice_pitch, ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_READ_IMAGE_ERR); - } - - cl_int enqueueWriteImage( - const Image& image, - cl_bool blocking, - const size_t<3>& origin, - const size_t<3>& region, - ::size_t row_pitch, - ::size_t slice_pitch, - void* ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueWriteImage( - object_, image(), blocking, (const ::size_t *) origin, - (const ::size_t *) region, row_pitch, slice_pitch, ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_WRITE_IMAGE_ERR); - } - - cl_int enqueueCopyImage( - const Image& src, - const Image& dst, - const size_t<3>& src_origin, - const size_t<3>& dst_origin, - const size_t<3>& region, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueCopyImage( - object_, src(), dst(), (const ::size_t *) src_origin, - (const ::size_t *)dst_origin, (const ::size_t *) region, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_COPY_IMAGE_ERR); - } - - cl_int enqueueCopyImageToBuffer( - const Image& src, - const Buffer& dst, - const size_t<3>& src_origin, - const size_t<3>& region, - ::size_t dst_offset, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueCopyImageToBuffer( - object_, src(), dst(), (const ::size_t *) src_origin, - (const ::size_t *) region, dst_offset, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR); - } - - cl_int enqueueCopyBufferToImage( - const Buffer& src, - const Image& dst, - ::size_t src_offset, - const size_t<3>& dst_origin, - const size_t<3>& region, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueCopyBufferToImage( - object_, src(), dst(), src_offset, - (const ::size_t *) dst_origin, (const ::size_t *) region, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR); - } - - void* enqueueMapBuffer( - const Buffer& buffer, - cl_bool blocking, - cl_map_flags flags, - ::size_t offset, - ::size_t size, - const VECTOR_CLASS* events = NULL, - Event* event = NULL, - cl_int* err = NULL) const - { - cl_int error; - void * result = ::clEnqueueMapBuffer( - object_, buffer(), blocking, flags, offset, size, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event, - &error); - - detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - return result; - } - - void* enqueueMapImage( - const Image& buffer, - cl_bool blocking, - cl_map_flags flags, - const size_t<3>& origin, - const size_t<3>& region, - ::size_t * row_pitch, - ::size_t * slice_pitch, - const VECTOR_CLASS* events = NULL, - Event* event = NULL, - cl_int* err = NULL) const - { - cl_int error; - void * result = ::clEnqueueMapImage( - object_, buffer(), blocking, flags, - (const ::size_t *) origin, (const ::size_t *) region, - row_pitch, slice_pitch, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event, - &error); - - detail::errHandler(error, __ENQUEUE_MAP_IMAGE_ERR); - if (err != NULL) { - *err = error; - } - return result; - } - - cl_int enqueueUnmapMemObject( - const Memory& memory, - void* mapped_ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueUnmapMemObject( - object_, memory(), mapped_ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_UNMAP_MEM_OBJECT_ERR); - } - - cl_int enqueueNDRangeKernel( - const Kernel& kernel, - const NDRange& offset, - const NDRange& global, - const NDRange& local, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueNDRangeKernel( - object_, kernel(), (cl_uint) global.dimensions(), - offset.dimensions() != 0 ? (const ::size_t*) offset : NULL, - (const ::size_t*) global, - local.dimensions() != 0 ? (const ::size_t*) local : NULL, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_NDRANGE_KERNEL_ERR); - } - - cl_int enqueueTask( - const Kernel& kernel, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueTask( - object_, kernel(), - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_TASK_ERR); - } - - cl_int enqueueNativeKernel( - void (*userFptr)(void *), - std::pair args, - const VECTOR_CLASS* mem_objects = NULL, - const VECTOR_CLASS* mem_locs = NULL, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_mem * mems = (mem_objects != NULL && mem_objects->size() > 0) - ? (cl_mem*) alloca(mem_objects->size() * sizeof(cl_mem)) - : NULL; - - if (mems != NULL) { - for (unsigned int i = 0; i < mem_objects->size(); i++) { - mems[i] = ((*mem_objects)[i])(); - } - } - - return detail::errHandler( - ::clEnqueueNativeKernel( - object_, userFptr, args.first, args.second, - (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, - mems, - (mem_locs != NULL) ? (const void **) &mem_locs->front() : NULL, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_NATIVE_KERNEL); - } - - cl_int enqueueMarker(Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueMarker(object_, (cl_event*) event), - __ENQUEUE_MARKER_ERR); - } - - cl_int enqueueWaitForEvents(const VECTOR_CLASS& events) const - { - return detail::errHandler( - ::clEnqueueWaitForEvents( - object_, - (cl_uint) events.size(), - (const cl_event*) &events.front()), - __ENQUEUE_WAIT_FOR_EVENTS_ERR); - } - - cl_int enqueueAcquireGLObjects( - const VECTOR_CLASS* mem_objects = NULL, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueAcquireGLObjects( - object_, - (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, - (mem_objects != NULL) ? (const cl_mem *) &mem_objects->front(): NULL, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_ACQUIRE_GL_ERR); - } - - cl_int enqueueReleaseGLObjects( - const VECTOR_CLASS* mem_objects = NULL, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueReleaseGLObjects( - object_, - (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, - (mem_objects != NULL) ? (const cl_mem *) &mem_objects->front(): NULL, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_RELEASE_GL_ERR); - } - -#if defined (USE_DX_INTEROP) -typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueAcquireD3D10ObjectsKHR)( - cl_command_queue command_queue, cl_uint num_objects, - const cl_mem* mem_objects, cl_uint num_events_in_wait_list, - const cl_event* event_wait_list, cl_event* event); -typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueReleaseD3D10ObjectsKHR)( - cl_command_queue command_queue, cl_uint num_objects, - const cl_mem* mem_objects, cl_uint num_events_in_wait_list, - const cl_event* event_wait_list, cl_event* event); - - cl_int enqueueAcquireD3D10Objects( - const VECTOR_CLASS* mem_objects = NULL, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - static PFN_clEnqueueAcquireD3D10ObjectsKHR pfn_clEnqueueAcquireD3D10ObjectsKHR = NULL; - __INIT_CL_EXT_FCN_PTR(clEnqueueAcquireD3D10ObjectsKHR); - - return detail::errHandler( - pfn_clEnqueueAcquireD3D10ObjectsKHR( - object_, - (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, - (mem_objects != NULL) ? (const cl_mem *) &mem_objects->front(): NULL, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_ACQUIRE_GL_ERR); - } - - cl_int enqueueReleaseD3D10Objects( - const VECTOR_CLASS* mem_objects = NULL, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - static PFN_clEnqueueReleaseD3D10ObjectsKHR pfn_clEnqueueReleaseD3D10ObjectsKHR = NULL; - __INIT_CL_EXT_FCN_PTR(clEnqueueReleaseD3D10ObjectsKHR); - - return detail::errHandler( - pfn_clEnqueueReleaseD3D10ObjectsKHR( - object_, - (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, - (mem_objects != NULL) ? (const cl_mem *) &mem_objects->front(): NULL, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_RELEASE_GL_ERR); - } -#endif - - cl_int enqueueBarrier() const - { - return detail::errHandler( - ::clEnqueueBarrier(object_), - __ENQUEUE_BARRIER_ERR); - } - - cl_int flush() const - { - return detail::errHandler(::clFlush(object_), __FLUSH_ERR); - } - - cl_int finish() const - { - return detail::errHandler(::clFinish(object_), __FINISH_ERR); - } -}; - -__GET_INFO_HELPER_WITH_RETAIN(cl::CommandQueue) - -/*! \class KernelFunctor - * \brief Kernel functor interface - * - * \note Currently only functors of zero to ten arguments are supported. It - * is straightforward to add more and a more general solution, similar to - * Boost.Lambda could be followed if required in the future. - */ -class KernelFunctor -{ -private: - Kernel kernel_; - CommandQueue queue_; - NDRange offset_; - NDRange global_; - NDRange local_; - - cl_int err_; -public: - KernelFunctor() { } - - KernelFunctor( - const Kernel& kernel, - const CommandQueue& queue, - const NDRange& offset, - const NDRange& global, - const NDRange& local) : - kernel_(kernel), - queue_(queue), - offset_(offset), - global_(global), - local_(local), - err_(CL_SUCCESS) - {} - - KernelFunctor& operator=(const KernelFunctor& rhs); - - KernelFunctor(const KernelFunctor& rhs); - - cl_int getError() { return err_; } - - inline Event operator()(const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const A12& a12, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const A12& a12, - const A13& a13, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const A12& a12, - const A13& a13, - const A14& a14, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const A12& a12, - const A13& a13, - const A14& a14, - const A15& a15, - const VECTOR_CLASS* events = NULL); -}; - -inline KernelFunctor Kernel::bind( - const CommandQueue& queue, - const NDRange& offset, - const NDRange& global, - const NDRange& local) -{ - return KernelFunctor(*this,queue,offset,global,local); -} - -inline KernelFunctor Kernel::bind( - const CommandQueue& queue, - const NDRange& global, - const NDRange& local) -{ - return KernelFunctor(*this,queue,NullRange,global,local); -} - -inline KernelFunctor& KernelFunctor::operator=(const KernelFunctor& rhs) -{ - if (this == &rhs) { - return *this; - } - - kernel_ = rhs.kernel_; - queue_ = rhs.queue_; - offset_ = rhs.offset_; - global_ = rhs.global_; - local_ = rhs.local_; - - return *this; -} - -inline KernelFunctor::KernelFunctor(const KernelFunctor& rhs) : - kernel_(rhs.kernel_), - queue_(rhs.queue_), - offset_(rhs.offset_), - global_(rhs.global_), - local_(rhs.local_) -{ -} - -Event KernelFunctor::operator()(const VECTOR_CLASS* events) -{ - Event event; - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - kernel_.setArg(6,a7); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - kernel_.setArg(6,a7); - kernel_.setArg(7,a8); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - kernel_.setArg(6,a7); - kernel_.setArg(7,a8); - kernel_.setArg(8,a9); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - kernel_.setArg(6,a7); - kernel_.setArg(7,a8); - kernel_.setArg(8,a9); - kernel_.setArg(9,a10); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - kernel_.setArg(6,a7); - kernel_.setArg(7,a8); - kernel_.setArg(8,a9); - kernel_.setArg(9,a10); - kernel_.setArg(10,a11); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const A12& a12, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - kernel_.setArg(6,a7); - kernel_.setArg(7,a8); - kernel_.setArg(8,a9); - kernel_.setArg(9,a10); - kernel_.setArg(10,a11); - kernel_.setArg(11,a12); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const A12& a12, - const A13& a13, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - kernel_.setArg(6,a7); - kernel_.setArg(7,a8); - kernel_.setArg(8,a9); - kernel_.setArg(9,a10); - kernel_.setArg(10,a11); - kernel_.setArg(11,a12); - kernel_.setArg(12,a13); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const A12& a12, - const A13& a13, - const A14& a14, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - kernel_.setArg(6,a7); - kernel_.setArg(7,a8); - kernel_.setArg(8,a9); - kernel_.setArg(9,a10); - kernel_.setArg(10,a11); - kernel_.setArg(11,a12); - kernel_.setArg(12,a13); - kernel_.setArg(13,a14); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const A12& a12, - const A13& a13, - const A14& a14, - const A15& a15, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - kernel_.setArg(6,a7); - kernel_.setArg(7,a8); - kernel_.setArg(8,a9); - kernel_.setArg(9,a10); - kernel_.setArg(10,a11); - kernel_.setArg(11,a12); - kernel_.setArg(12,a13); - kernel_.setArg(13,a14); - kernel_.setArg(14,a15); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -#undef __ERR_STR -#if !defined(__CL_USER_OVERRIDE_ERROR_STRINGS) -#undef __GET_DEVICE_INFO_ERR -#undef __GET_PLATFORM_INFO_ERR -#undef __GET_DEVICE_IDS_ERR -#undef __GET_CONTEXT_INFO_ERR -#undef __GET_EVENT_INFO_ERR -#undef __GET_EVENT_PROFILE_INFO_ERR -#undef __GET_MEM_OBJECT_INFO_ERR -#undef __GET_IMAGE_INFO_ERR -#undef __GET_SAMPLER_INFO_ERR -#undef __GET_KERNEL_INFO_ERR -#undef __GET_KERNEL_WORK_GROUP_INFO_ERR -#undef __GET_PROGRAM_INFO_ERR -#undef __GET_PROGRAM_BUILD_INFO_ERR -#undef __GET_COMMAND_QUEUE_INFO_ERR - -#undef __CREATE_CONTEXT_FROM_TYPE_ERR -#undef __GET_SUPPORTED_IMAGE_FORMATS_ERR - -#undef __CREATE_BUFFER_ERR -#undef __CREATE_SUBBUFFER_ERR -#undef __CREATE_IMAGE2D_ERR -#undef __CREATE_IMAGE3D_ERR -#undef __CREATE_SAMPLER_ERR -#undef __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR - -#undef __CREATE_USER_EVENT_ERR -#undef __SET_USER_EVENT_STATUS_ERR -#undef __SET_EVENT_CALLBACK_ERR - -#undef __WAIT_FOR_EVENTS_ERR - -#undef __CREATE_KERNEL_ERR -#undef __SET_KERNEL_ARGS_ERR -#undef __CREATE_PROGRAM_WITH_SOURCE_ERR -#undef __CREATE_PROGRAM_WITH_BINARY_ERR -#undef __BUILD_PROGRAM_ERR -#undef __CREATE_KERNELS_IN_PROGRAM_ERR - -#undef __CREATE_COMMAND_QUEUE_ERR -#undef __SET_COMMAND_QUEUE_PROPERTY_ERR -#undef __ENQUEUE_READ_BUFFER_ERR -#undef __ENQUEUE_WRITE_BUFFER_ERR -#undef __ENQUEUE_READ_BUFFER_RECT_ERR -#undef __ENQUEUE_WRITE_BUFFER_RECT_ERR -#undef __ENQEUE_COPY_BUFFER_ERR -#undef __ENQEUE_COPY_BUFFER_RECT_ERR -#undef __ENQUEUE_READ_IMAGE_ERR -#undef __ENQUEUE_WRITE_IMAGE_ERR -#undef __ENQUEUE_COPY_IMAGE_ERR -#undef __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR -#undef __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR -#undef __ENQUEUE_MAP_BUFFER_ERR -#undef __ENQUEUE_MAP_IMAGE_ERR -#undef __ENQUEUE_UNMAP_MEM_OBJECT_ERR -#undef __ENQUEUE_NDRANGE_KERNEL_ERR -#undef __ENQUEUE_TASK_ERR -#undef __ENQUEUE_NATIVE_KERNEL - -#undef __UNLOAD_COMPILER_ERR -#endif //__CL_USER_OVERRIDE_ERROR_STRINGS - -#undef __GET_INFO_HELPER_WITH_RETAIN - -// Extensions -#undef __INIT_CL_EXT_FCN_PTR -#undef __CREATE_SUB_DEVICES - -#if defined(USE_CL_DEVICE_FISSION) -#undef __PARAM_NAME_DEVICE_FISSION -#endif // USE_CL_DEVICE_FISSION - -} // namespace cl - -#endif // CL_HPP_ diff --git a/KEMField/opencl/1.1/CL/cl_ext.h b/KEMField/opencl/1.1/CL/cl_ext.h deleted file mode 100644 index 4e92c7e63..000000000 --- a/KEMField/opencl/1.1/CL/cl_ext.h +++ /dev/null @@ -1,213 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008-2010 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and/or associated documentation files (the - * "Materials"), to deal in the Materials without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Materials, and to - * permit persons to whom the Materials are 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 Materials. - * - * THE MATERIALS ARE 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 - * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. - ******************************************************************************/ - -/* $Revision: 11928 $ on $Date: 2010-07-13 09:04:56 -0700 (Tue, 13 Jul 2010) $ */ - -/* cl_ext.h contains OpenCL extensions which don't have external */ -/* (OpenGL, D3D) dependencies. */ - -#ifndef __CL_EXT_H -#define __CL_EXT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __APPLE__ - #include - #include -#else - #include -#endif - -/* cl_khr_fp64 extension - no extension #define since it has no functions */ -#define CL_DEVICE_DOUBLE_FP_CONFIG 0x1032 - -/* cl_khr_fp16 extension - no extension #define since it has no functions */ -#define CL_DEVICE_HALF_FP_CONFIG 0x1033 - -/* Memory object destruction - * - * Apple extension for use to manage externally allocated buffers used with cl_mem objects with CL_MEM_USE_HOST_PTR - * - * Registers a user callback function that will be called when the memory object is deleted and its resources - * freed. Each call to clSetMemObjectCallbackFn registers the specified user callback function on a callback - * stack associated with memobj. The registered user callback functions are called in the reverse order in - * which they were registered. The user callback functions are called and then the memory object is deleted - * and its resources freed. This provides a mechanism for the application (and libraries) using memobj to be - * notified when the memory referenced by host_ptr, specified when the memory object is created and used as - * the storage bits for the memory object, can be reused or freed. - * - * The application may not call CL api's with the cl_mem object passed to the pfn_notify. - * - * Please check for the "cl_APPLE_SetMemObjectDestructor" extension using clGetDeviceInfo(CL_DEVICE_EXTENSIONS) - * before using. - */ -#define cl_APPLE_SetMemObjectDestructor 1 -cl_int CL_API_ENTRY clSetMemObjectDestructorAPPLE( cl_mem /* memobj */, - void (* /*pfn_notify*/)( cl_mem /* memobj */, void* /*user_data*/), - void * /*user_data */ ) CL_EXT_SUFFIX__VERSION_1_0; - - -/* Context Logging Functions - * - * The next three convenience functions are intended to be used as the pfn_notify parameter to clCreateContext(). - * Please check for the "cl_APPLE_ContextLoggingFunctions" extension using clGetDeviceInfo(CL_DEVICE_EXTENSIONS) - * before using. - * - * clLogMessagesToSystemLog fowards on all log messages to the Apple System Logger - */ -#define cl_APPLE_ContextLoggingFunctions 1 -extern void CL_API_ENTRY clLogMessagesToSystemLogAPPLE( const char * /* errstr */, - const void * /* private_info */, - size_t /* cb */, - void * /* user_data */ ) CL_EXT_SUFFIX__VERSION_1_0; - -/* clLogMessagesToStdout sends all log messages to the file descriptor stdout */ -extern void CL_API_ENTRY clLogMessagesToStdoutAPPLE( const char * /* errstr */, - const void * /* private_info */, - size_t /* cb */, - void * /* user_data */ ) CL_EXT_SUFFIX__VERSION_1_0; - -/* clLogMessagesToStderr sends all log messages to the file descriptor stderr */ -extern void CL_API_ENTRY clLogMessagesToStderrAPPLE( const char * /* errstr */, - const void * /* private_info */, - size_t /* cb */, - void * /* user_data */ ) CL_EXT_SUFFIX__VERSION_1_0; - - -/************************ -* cl_khr_icd extension * -************************/ -#define cl_khr_icd 1 - -/* cl_platform_info */ -#define CL_PLATFORM_ICD_SUFFIX_KHR 0x0920 - -/* Additional Error Codes */ -#define CL_PLATFORM_NOT_FOUND_KHR -1001 - -extern CL_API_ENTRY cl_int CL_API_CALL -clIcdGetPlatformIDsKHR(cl_uint /* num_entries */, - cl_platform_id * /* platforms */, - cl_uint * /* num_platforms */); - -typedef CL_API_ENTRY cl_int (CL_API_CALL *clIcdGetPlatformIDsKHR_fn)( - cl_uint /* num_entries */, - cl_platform_id * /* platforms */, - cl_uint * /* num_platforms */); - - -/****************************************** -* cl_nv_device_attribute_query extension * -******************************************/ -/* cl_nv_device_attribute_query extension - no extension #define since it has no functions */ -#define CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV 0x4000 -#define CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV 0x4001 -#define CL_DEVICE_REGISTERS_PER_BLOCK_NV 0x4002 -#define CL_DEVICE_WARP_SIZE_NV 0x4003 -#define CL_DEVICE_GPU_OVERLAP_NV 0x4004 -#define CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV 0x4005 -#define CL_DEVICE_INTEGRATED_MEMORY_NV 0x4006 - - -/********************************* -* cl_amd_device_attribute_query * -*********************************/ -#define CL_DEVICE_PROFILING_TIMER_OFFSET_AMD 0x4036 - - -#ifdef CL_VERSION_1_1 - /*********************************** - * cl_ext_device_fission extension * - ***********************************/ - #define cl_ext_device_fission 1 - - extern CL_API_ENTRY cl_int CL_API_CALL - clReleaseDeviceEXT( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1; - - typedef CL_API_ENTRY cl_int - (CL_API_CALL *clReleaseDeviceEXT_fn)( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1; - - extern CL_API_ENTRY cl_int CL_API_CALL - clRetainDeviceEXT( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1; - - typedef CL_API_ENTRY cl_int - (CL_API_CALL *clRetainDeviceEXT_fn)( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1; - - typedef cl_ulong cl_device_partition_property_ext; - extern CL_API_ENTRY cl_int CL_API_CALL - clCreateSubDevicesEXT( cl_device_id /*in_device*/, - const cl_device_partition_property_ext * /* properties */, - cl_uint /*num_entries*/, - cl_device_id * /*out_devices*/, - cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1; - - typedef CL_API_ENTRY cl_int - ( CL_API_CALL * clCreateSubDevicesEXT_fn)( cl_device_id /*in_device*/, - const cl_device_partition_property_ext * /* properties */, - cl_uint /*num_entries*/, - cl_device_id * /*out_devices*/, - cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1; - - /* cl_device_partition_property_ext */ - #define CL_DEVICE_PARTITION_EQUALLY_EXT 0x4050 - #define CL_DEVICE_PARTITION_BY_COUNTS_EXT 0x4051 - #define CL_DEVICE_PARTITION_BY_NAMES_EXT 0x4052 - #define CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN_EXT 0x4053 - - /* clDeviceGetInfo selectors */ - #define CL_DEVICE_PARENT_DEVICE_EXT 0x4054 - #define CL_DEVICE_PARTITION_TYPES_EXT 0x4055 - #define CL_DEVICE_AFFINITY_DOMAINS_EXT 0x4056 - #define CL_DEVICE_REFERENCE_COUNT_EXT 0x4057 - #define CL_DEVICE_PARTITION_STYLE_EXT 0x4058 - - /* error codes */ - #define CL_DEVICE_PARTITION_FAILED_EXT -1057 - #define CL_INVALID_PARTITION_COUNT_EXT -1058 - #define CL_INVALID_PARTITION_NAME_EXT -1059 - - /* CL_AFFINITY_DOMAINs */ - #define CL_AFFINITY_DOMAIN_L1_CACHE_EXT 0x1 - #define CL_AFFINITY_DOMAIN_L2_CACHE_EXT 0x2 - #define CL_AFFINITY_DOMAIN_L3_CACHE_EXT 0x3 - #define CL_AFFINITY_DOMAIN_L4_CACHE_EXT 0x4 - #define CL_AFFINITY_DOMAIN_NUMA_EXT 0x10 - #define CL_AFFINITY_DOMAIN_NEXT_FISSIONABLE_EXT 0x100 - - /* cl_device_partition_property_ext list terminators */ - #define CL_PROPERTIES_LIST_END_EXT ((cl_device_partition_property_ext) 0) - #define CL_PARTITION_BY_COUNTS_LIST_END_EXT ((cl_device_partition_property_ext) 0) - #define CL_PARTITION_BY_NAMES_LIST_END_EXT ((cl_device_partition_property_ext) 0 - 1) - - - -#endif /* CL_VERSION_1_1 */ - -#ifdef __cplusplus -} -#endif - - -#endif /* __CL_EXT_H */ diff --git a/KEMField/opencl/1.1/CL/cl_gl.h b/KEMField/opencl/1.1/CL/cl_gl.h deleted file mode 100644 index 3b4fe0690..000000000 --- a/KEMField/opencl/1.1/CL/cl_gl.h +++ /dev/null @@ -1,155 +0,0 @@ -/********************************************************************************** - * Copyright (c) 2008-2010 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and/or associated documentation files (the - * "Materials"), to deal in the Materials without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Materials, and to - * permit persons to whom the Materials are 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 Materials. - * - * THE MATERIALS ARE 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 - * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. - **********************************************************************************/ - -/* $Revision: 11708 $ on $Date: 2010-06-13 23:36:24 -0700 (Sun, 13 Jun 2010) $ */ - -/* - * cl_gl.h contains Khronos-approved (KHR) OpenCL extensions which have - * OpenGL dependencies. The application is responsible for #including - * OpenGL or OpenGL ES headers before #including cl_gl.h. - */ - -#ifndef __OPENCL_CL_GL_H -#define __OPENCL_CL_GL_H - -#ifdef __APPLE__ -#include -#include -#else -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef cl_uint cl_gl_object_type; -typedef cl_uint cl_gl_texture_info; -typedef cl_uint cl_gl_platform_info; -typedef struct __GLsync *cl_GLsync; - -/* cl_gl_object_type */ -#define CL_GL_OBJECT_BUFFER 0x2000 -#define CL_GL_OBJECT_TEXTURE2D 0x2001 -#define CL_GL_OBJECT_TEXTURE3D 0x2002 -#define CL_GL_OBJECT_RENDERBUFFER 0x2003 - -/* cl_gl_texture_info */ -#define CL_GL_TEXTURE_TARGET 0x2004 -#define CL_GL_MIPMAP_LEVEL 0x2005 - -extern CL_API_ENTRY cl_mem CL_API_CALL -clCreateFromGLBuffer(cl_context /* context */, - cl_mem_flags /* flags */, - cl_GLuint /* bufobj */, - int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_mem CL_API_CALL -clCreateFromGLTexture2D(cl_context /* context */, - cl_mem_flags /* flags */, - cl_GLenum /* target */, - cl_GLint /* miplevel */, - cl_GLuint /* texture */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_mem CL_API_CALL -clCreateFromGLTexture3D(cl_context /* context */, - cl_mem_flags /* flags */, - cl_GLenum /* target */, - cl_GLint /* miplevel */, - cl_GLuint /* texture */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_mem CL_API_CALL -clCreateFromGLRenderbuffer(cl_context /* context */, - cl_mem_flags /* flags */, - cl_GLuint /* renderbuffer */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clGetGLObjectInfo(cl_mem /* memobj */, - cl_gl_object_type * /* gl_object_type */, - cl_GLuint * /* gl_object_name */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clGetGLTextureInfo(cl_mem /* memobj */, - cl_gl_texture_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueAcquireGLObjects(cl_command_queue /* command_queue */, - cl_uint /* num_objects */, - const cl_mem * /* mem_objects */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueReleaseGLObjects(cl_command_queue /* command_queue */, - cl_uint /* num_objects */, - const cl_mem * /* mem_objects */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -/* cl_khr_gl_sharing extension */ - -#define cl_khr_gl_sharing 1 - -typedef cl_uint cl_gl_context_info; - -/* Additional Error Codes */ -#define CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR -1000 - -/* cl_gl_context_info */ -#define CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR 0x2006 -#define CL_DEVICES_FOR_GL_CONTEXT_KHR 0x2007 - -/* Additional cl_context_properties */ -#define CL_GL_CONTEXT_KHR 0x2008 -#define CL_EGL_DISPLAY_KHR 0x2009 -#define CL_GLX_DISPLAY_KHR 0x200A -#define CL_WGL_HDC_KHR 0x200B -#define CL_CGL_SHAREGROUP_KHR 0x200C - -extern CL_API_ENTRY cl_int CL_API_CALL -clGetGLContextInfoKHR(const cl_context_properties * /* properties */, - cl_gl_context_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetGLContextInfoKHR_fn)( - const cl_context_properties * properties, - cl_gl_context_info param_name, - size_t param_value_size, - void * param_value, - size_t * param_value_size_ret); - -#ifdef __cplusplus -} -#endif - -#endif /* __OPENCL_CL_GL_H */ diff --git a/KEMField/opencl/1.1/CL/cl_gl_ext.h b/KEMField/opencl/1.1/CL/cl_gl_ext.h deleted file mode 100644 index 26e47821f..000000000 --- a/KEMField/opencl/1.1/CL/cl_gl_ext.h +++ /dev/null @@ -1,69 +0,0 @@ -/********************************************************************************** - * Copyright (c) 2008-2010 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and/or associated documentation files (the - * "Materials"), to deal in the Materials without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Materials, and to - * permit persons to whom the Materials are 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 Materials. - * - * THE MATERIALS ARE 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 - * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. - **********************************************************************************/ - -/* $Revision: 11708 $ on $Date: 2010-06-13 23:36:24 -0700 (Sun, 13 Jun 2010) $ */ - -/* cl_gl_ext.h contains vendor (non-KHR) OpenCL extensions which have */ -/* OpenGL dependencies. */ - -#ifndef __OPENCL_CL_GL_EXT_H -#define __OPENCL_CL_GL_EXT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __APPLE__ - #include -#else - #include -#endif - -/* - * For each extension, follow this template - * /* cl_VEN_extname extension */ -/* #define cl_VEN_extname 1 - * ... define new types, if any - * ... define new tokens, if any - * ... define new APIs, if any - * - * If you need GLtypes here, mirror them with a cl_GLtype, rather than including a GL header - * This allows us to avoid having to decide whether to include GL headers or GLES here. - */ - -/* - * cl_khr_gl_event extension - * See section 9.9 in the OpenCL 1.1 spec for more information - */ -#define CL_COMMAND_GL_FENCE_SYNC_OBJECT_KHR 0x200D - -extern CL_API_ENTRY cl_event CL_API_CALL -clCreateEventFromGLsyncKHR(cl_context /* context */, - cl_GLsync /* cl_GLsync */, - cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1; - -#ifdef __cplusplus -} -#endif - -#endif /* __OPENCL_CL_GL_EXT_H */ diff --git a/KEMField/opencl/1.1/CL/cl_platform.h b/KEMField/opencl/1.1/CL/cl_platform.h deleted file mode 100644 index 043b0489d..000000000 --- a/KEMField/opencl/1.1/CL/cl_platform.h +++ /dev/null @@ -1,1198 +0,0 @@ -/********************************************************************************** - * Copyright (c) 2008-2010 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and/or associated documentation files (the - * "Materials"), to deal in the Materials without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Materials, and to - * permit persons to whom the Materials are 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 Materials. - * - * THE MATERIALS ARE 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 - * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. - **********************************************************************************/ - -/* $Revision: 11803 $ on $Date: 2010-06-25 10:02:12 -0700 (Fri, 25 Jun 2010) $ */ - -#ifndef __CL_PLATFORM_H -#define __CL_PLATFORM_H - -#ifdef __APPLE__ - /* Contains #defines for AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER below */ - #include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(_WIN32) - #define CL_API_ENTRY - #define CL_API_CALL __stdcall - #define CL_CALLBACK __stdcall -#else - #define CL_API_ENTRY - #define CL_API_CALL - #define CL_CALLBACK -#endif - -#ifdef __APPLE__ - #define CL_EXTENSION_WEAK_LINK __attribute__((weak_import)) - #define CL_API_SUFFIX__VERSION_1_0 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER - #define CL_EXT_SUFFIX__VERSION_1_0 CL_EXTENSION_WEAK_LINK AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER - #define CL_API_SUFFIX__VERSION_1_1 CL_EXTENSION_WEAK_LINK - #define CL_EXT_SUFFIX__VERSION_1_1 CL_EXTENSION_WEAK_LINK - #define CL_EXT_SUFFIX__VERSION_1_0_DEPRECATED CL_EXTENSION_WEAK_LINK AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER -#else - #define CL_EXTENSION_WEAK_LINK - #define CL_API_SUFFIX__VERSION_1_0 - #define CL_EXT_SUFFIX__VERSION_1_0 - #define CL_API_SUFFIX__VERSION_1_1 - #define CL_EXT_SUFFIX__VERSION_1_1 - #define CL_EXT_SUFFIX__VERSION_1_0_DEPRECATED -#endif - -#if (defined (_WIN32) && defined(_MSC_VER)) - -/* scalar types */ -typedef signed __int8 cl_char; -typedef unsigned __int8 cl_uchar; -typedef signed __int16 cl_short; -typedef unsigned __int16 cl_ushort; -typedef signed __int32 cl_int; -typedef unsigned __int32 cl_uint; -typedef signed __int64 cl_long; -typedef unsigned __int64 cl_ulong; - -typedef unsigned __int16 cl_half; -typedef float cl_float; -typedef double cl_double; - -/* Macro names and corresponding values defined by OpenCL */ -#define CL_CHAR_BIT 8 -#define CL_SCHAR_MAX 127 -#define CL_SCHAR_MIN (-127-1) -#define CL_CHAR_MAX CL_SCHAR_MAX -#define CL_CHAR_MIN CL_SCHAR_MIN -#define CL_UCHAR_MAX 255 -#define CL_SHRT_MAX 32767 -#define CL_SHRT_MIN (-32767-1) -#define CL_USHRT_MAX 65535 -#define CL_INT_MAX 2147483647 -#define CL_INT_MIN (-2147483647-1) -#define CL_UINT_MAX 0xffffffffU -#define CL_LONG_MAX ((cl_long) 0x7FFFFFFFFFFFFFFFLL) -#define CL_LONG_MIN ((cl_long) -0x7FFFFFFFFFFFFFFFLL - 1LL) -#define CL_ULONG_MAX ((cl_ulong) 0xFFFFFFFFFFFFFFFFULL) - -#define CL_FLT_DIG 6 -#define CL_FLT_MANT_DIG 24 -#define CL_FLT_MAX_10_EXP +38 -#define CL_FLT_MAX_EXP +128 -#define CL_FLT_MIN_10_EXP -37 -#define CL_FLT_MIN_EXP -125 -#define CL_FLT_RADIX 2 -#define CL_FLT_MAX 340282346638528859811704183484516925440.0f -#define CL_FLT_MIN 1.175494350822287507969e-38f -#define CL_FLT_EPSILON 0x1.0p-23f - -#define CL_DBL_DIG 15 -#define CL_DBL_MANT_DIG 53 -#define CL_DBL_MAX_10_EXP +308 -#define CL_DBL_MAX_EXP +1024 -#define CL_DBL_MIN_10_EXP -307 -#define CL_DBL_MIN_EXP -1021 -#define CL_DBL_RADIX 2 -#define CL_DBL_MAX 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0 -#define CL_DBL_MIN 2.225073858507201383090e-308 -#define CL_DBL_EPSILON 2.220446049250313080847e-16 - -#define CL_M_E 2.718281828459045090796 -#define CL_M_LOG2E 1.442695040888963387005 -#define CL_M_LOG10E 0.434294481903251816668 -#define CL_M_LN2 0.693147180559945286227 -#define CL_M_LN10 2.302585092994045901094 -#define CL_M_PI 3.141592653589793115998 -#define CL_M_PI_2 1.570796326794896557999 -#define CL_M_PI_4 0.785398163397448278999 -#define CL_M_1_PI 0.318309886183790691216 -#define CL_M_2_PI 0.636619772367581382433 -#define CL_M_2_SQRTPI 1.128379167095512558561 -#define CL_M_SQRT2 1.414213562373095145475 -#define CL_M_SQRT1_2 0.707106781186547572737 - -#define CL_M_E_F 2.71828174591064f -#define CL_M_LOG2E_F 1.44269502162933f -#define CL_M_LOG10E_F 0.43429449200630f -#define CL_M_LN2_F 0.69314718246460f -#define CL_M_LN10_F 2.30258512496948f -#define CL_M_PI_F 3.14159274101257f -#define CL_M_PI_2_F 1.57079637050629f -#define CL_M_PI_4_F 0.78539818525314f -#define CL_M_1_PI_F 0.31830987334251f -#define CL_M_2_PI_F 0.63661974668503f -#define CL_M_2_SQRTPI_F 1.12837922573090f -#define CL_M_SQRT2_F 1.41421353816986f -#define CL_M_SQRT1_2_F 0.70710676908493f - -#define CL_NAN (CL_INFINITY - CL_INFINITY) -#define CL_HUGE_VALF ((cl_float) 1e50) -#define CL_HUGE_VAL ((cl_double) 1e500) -#define CL_MAXFLOAT CL_FLT_MAX -#define CL_INFINITY CL_HUGE_VALF - -#else - -#include - -/* scalar types */ -typedef int8_t cl_char; -typedef uint8_t cl_uchar; -typedef int16_t cl_short __attribute__((aligned(2))); -typedef uint16_t cl_ushort __attribute__((aligned(2))); -typedef int32_t cl_int __attribute__((aligned(4))); -typedef uint32_t cl_uint __attribute__((aligned(4))); -typedef int64_t cl_long __attribute__((aligned(8))); -typedef uint64_t cl_ulong __attribute__((aligned(8))); - -typedef uint16_t cl_half __attribute__((aligned(2))); -typedef float cl_float __attribute__((aligned(4))); -typedef double cl_double __attribute__((aligned(8))); - -/* Macro names and corresponding values defined by OpenCL */ -#define CL_CHAR_BIT 8 -#define CL_SCHAR_MAX 127 -#define CL_SCHAR_MIN (-127-1) -#define CL_CHAR_MAX CL_SCHAR_MAX -#define CL_CHAR_MIN CL_SCHAR_MIN -#define CL_UCHAR_MAX 255 -#define CL_SHRT_MAX 32767 -#define CL_SHRT_MIN (-32767-1) -#define CL_USHRT_MAX 65535 -#define CL_INT_MAX 2147483647 -#define CL_INT_MIN (-2147483647-1) -#define CL_UINT_MAX 0xffffffffU -#define CL_LONG_MAX ((cl_long) 0x7FFFFFFFFFFFFFFFLL) -#define CL_LONG_MIN ((cl_long) -0x7FFFFFFFFFFFFFFFLL - 1LL) -#define CL_ULONG_MAX ((cl_ulong) 0xFFFFFFFFFFFFFFFFULL) - -#define CL_FLT_DIG 6 -#define CL_FLT_MANT_DIG 24 -#define CL_FLT_MAX_10_EXP +38 -#define CL_FLT_MAX_EXP +128 -#define CL_FLT_MIN_10_EXP -37 -#define CL_FLT_MIN_EXP -125 -#define CL_FLT_RADIX 2 -#define CL_FLT_MAX 0x1.fffffep127f -#define CL_FLT_MIN 0x1.0p-126f -#define CL_FLT_EPSILON 0x1.0p-23f - -#define CL_DBL_DIG 15 -#define CL_DBL_MANT_DIG 53 -#define CL_DBL_MAX_10_EXP +308 -#define CL_DBL_MAX_EXP +1024 -#define CL_DBL_MIN_10_EXP -307 -#define CL_DBL_MIN_EXP -1021 -#define CL_DBL_RADIX 2 -#define CL_DBL_MAX 0x1.fffffffffffffp1023 -#define CL_DBL_MIN 0x1.0p-1022 -#define CL_DBL_EPSILON 0x1.0p-52 - -#define CL_M_E 2.718281828459045090796 -#define CL_M_LOG2E 1.442695040888963387005 -#define CL_M_LOG10E 0.434294481903251816668 -#define CL_M_LN2 0.693147180559945286227 -#define CL_M_LN10 2.302585092994045901094 -#define CL_M_PI 3.141592653589793115998 -#define CL_M_PI_2 1.570796326794896557999 -#define CL_M_PI_4 0.785398163397448278999 -#define CL_M_1_PI 0.318309886183790691216 -#define CL_M_2_PI 0.636619772367581382433 -#define CL_M_2_SQRTPI 1.128379167095512558561 -#define CL_M_SQRT2 1.414213562373095145475 -#define CL_M_SQRT1_2 0.707106781186547572737 - -#define CL_M_E_F 2.71828174591064f -#define CL_M_LOG2E_F 1.44269502162933f -#define CL_M_LOG10E_F 0.43429449200630f -#define CL_M_LN2_F 0.69314718246460f -#define CL_M_LN10_F 2.30258512496948f -#define CL_M_PI_F 3.14159274101257f -#define CL_M_PI_2_F 1.57079637050629f -#define CL_M_PI_4_F 0.78539818525314f -#define CL_M_1_PI_F 0.31830987334251f -#define CL_M_2_PI_F 0.63661974668503f -#define CL_M_2_SQRTPI_F 1.12837922573090f -#define CL_M_SQRT2_F 1.41421353816986f -#define CL_M_SQRT1_2_F 0.70710676908493f - -#if defined( __GNUC__ ) - #define CL_HUGE_VALF __builtin_huge_valf() - #define CL_HUGE_VAL __builtin_huge_val() - #define CL_NAN __builtin_nanf( "" ) -#else - #define CL_HUGE_VALF ((cl_float) 1e50) - #define CL_HUGE_VAL ((cl_double) 1e500) - float nanf( const char * ); - #define CL_NAN nanf( "" ) -#endif -#define CL_MAXFLOAT CL_FLT_MAX -#define CL_INFINITY CL_HUGE_VALF - -#endif - -#include - -/* Mirror types to GL types. Mirror types allow us to avoid deciding which headers to load based on whether we are using GL or GLES here. */ -typedef unsigned int cl_GLuint; -typedef int cl_GLint; -typedef unsigned int cl_GLenum; - -/* - * Vector types - * - * Note: OpenCL requires that all types be naturally aligned. - * This means that vector types must be naturally aligned. - * For example, a vector of four floats must be aligned to - * a 16 byte boundary (calculated as 4 * the natural 4-byte - * alignment of the float). The alignment qualifiers here - * will only function properly if your compiler supports them - * and if you don't actively work to defeat them. For example, - * in order for a cl_float4 to be 16 byte aligned in a struct, - * the start of the struct must itself be 16-byte aligned. - * - * Maintaining proper alignment is the user's responsibility. - */ - -/* Define basic vector types */ -#if defined( __VEC__ ) - #include /* may be omitted depending on compiler. AltiVec spec provides no way to detect whether the header is required. */ - typedef vector unsigned char __cl_uchar16; - typedef vector signed char __cl_char16; - typedef vector unsigned short __cl_ushort8; - typedef vector signed short __cl_short8; - typedef vector unsigned int __cl_uint4; - typedef vector signed int __cl_int4; - typedef vector float __cl_float4; - #define __CL_UCHAR16__ 1 - #define __CL_CHAR16__ 1 - #define __CL_USHORT8__ 1 - #define __CL_SHORT8__ 1 - #define __CL_UINT4__ 1 - #define __CL_INT4__ 1 - #define __CL_FLOAT4__ 1 -#endif - -#if defined( __SSE__ ) - #if defined( __MINGW64__ ) - #include - #else - #include - #endif - #if defined( __GNUC__ ) - typedef float __cl_float4 __attribute__((vector_size(16))); - #else - typedef __m128 __cl_float4; - #endif - #define __CL_FLOAT4__ 1 -#endif - -#if defined( __SSE2__ ) - #if defined( __MINGW64__ ) - #include - #else - #include - #endif - #if defined( __GNUC__ ) - typedef cl_uchar __cl_uchar16 __attribute__((vector_size(16))); - typedef cl_char __cl_char16 __attribute__((vector_size(16))); - typedef cl_ushort __cl_ushort8 __attribute__((vector_size(16))); - typedef cl_short __cl_short8 __attribute__((vector_size(16))); - typedef cl_uint __cl_uint4 __attribute__((vector_size(16))); - typedef cl_int __cl_int4 __attribute__((vector_size(16))); - typedef cl_ulong __cl_ulong2 __attribute__((vector_size(16))); - typedef cl_long __cl_long2 __attribute__((vector_size(16))); - typedef cl_double __cl_double2 __attribute__((vector_size(16))); - #else - typedef __m128i __cl_uchar16; - typedef __m128i __cl_char16; - typedef __m128i __cl_ushort8; - typedef __m128i __cl_short8; - typedef __m128i __cl_uint4; - typedef __m128i __cl_int4; - typedef __m128i __cl_ulong2; - typedef __m128i __cl_long2; - typedef __m128d __cl_double2; - #endif - #define __CL_UCHAR16__ 1 - #define __CL_CHAR16__ 1 - #define __CL_USHORT8__ 1 - #define __CL_SHORT8__ 1 - #define __CL_INT4__ 1 - #define __CL_UINT4__ 1 - #define __CL_ULONG2__ 1 - #define __CL_LONG2__ 1 - #define __CL_DOUBLE2__ 1 -#endif - -#if defined( __MMX__ ) - #include - #if defined( __GNUC__ ) - typedef cl_uchar __cl_uchar8 __attribute__((vector_size(8))); - typedef cl_char __cl_char8 __attribute__((vector_size(8))); - typedef cl_ushort __cl_ushort4 __attribute__((vector_size(8))); - typedef cl_short __cl_short4 __attribute__((vector_size(8))); - typedef cl_uint __cl_uint2 __attribute__((vector_size(8))); - typedef cl_int __cl_int2 __attribute__((vector_size(8))); - typedef cl_ulong __cl_ulong1 __attribute__((vector_size(8))); - typedef cl_long __cl_long1 __attribute__((vector_size(8))); - typedef cl_float __cl_float2 __attribute__((vector_size(8))); - #else - typedef __m64 __cl_uchar8; - typedef __m64 __cl_char8; - typedef __m64 __cl_ushort4; - typedef __m64 __cl_short4; - typedef __m64 __cl_uint2; - typedef __m64 __cl_int2; - typedef __m64 __cl_ulong1; - typedef __m64 __cl_long1; - typedef __m64 __cl_float2; - #endif - #define __CL_UCHAR8__ 1 - #define __CL_CHAR8__ 1 - #define __CL_USHORT4__ 1 - #define __CL_SHORT4__ 1 - #define __CL_INT2__ 1 - #define __CL_UINT2__ 1 - #define __CL_ULONG1__ 1 - #define __CL_LONG1__ 1 - #define __CL_FLOAT2__ 1 -#endif - -#if defined( __AVX__ ) - #if defined( __MINGW64__ ) - #include - #else - #include - #endif - #if defined( __GNUC__ ) - typedef cl_float __cl_float8 __attribute__((vector_size(32))); - typedef cl_double __cl_double4 __attribute__((vector_size(32))); - #else - typedef __m256 __cl_float8; - typedef __m256d __cl_double4; - #endif - #define __CL_FLOAT8__ 1 - #define __CL_DOUBLE4__ 1 -#endif - -/* Define alignment keys */ -#if defined( __GNUC__ ) - #define CL_ALIGNED(_x) __attribute__ ((aligned(_x))) -#elif defined( _WIN32) && (_MSC_VER) - /* Alignment keys neutered on windows because MSVC can't swallow function arguments with alignment requirements */ - /* http://msdn.microsoft.com/en-us/library/373ak2y1%28VS.71%29.aspx */ - /* #include */ - /* #define CL_ALIGNED(_x) _CRT_ALIGN(_x) */ - #define CL_ALIGNED(_x) -#else - #warning Need to implement some method to align data here - #define CL_ALIGNED(_x) -#endif - -/* Indicate whether .xyzw, .s0123 and .hi.lo are supported */ -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - /* .xyzw and .s0123...{f|F} are supported */ - #define CL_HAS_NAMED_VECTOR_FIELDS 1 - /* .hi and .lo are supported */ - #define CL_HAS_HI_LO_VECTOR_FIELDS 1 -#endif - -/* Define cl_vector types */ - -/* ---- cl_charn ---- */ -typedef union -{ - cl_char CL_ALIGNED(2) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_char x, y; }; - __extension__ struct{ cl_char s0, s1; }; - __extension__ struct{ cl_char lo, hi; }; -#endif -#if defined( __CL_CHAR2__) - __cl_char2 v2; -#endif -}cl_char2; - -typedef union -{ - cl_char CL_ALIGNED(4) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_char x, y, z, w; }; - __extension__ struct{ cl_char s0, s1, s2, s3; }; - __extension__ struct{ cl_char2 lo, hi; }; -#endif -#if defined( __CL_CHAR2__) - __cl_char2 v2[2]; -#endif -#if defined( __CL_CHAR4__) - __cl_char4 v4; -#endif -}cl_char4; - -/* cl_char3 is identical in size, alignment and behavior to cl_char4. See section 6.1.5. */ -typedef cl_char4 cl_char3; - -typedef union -{ - cl_char CL_ALIGNED(8) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_char x, y, z, w; }; - __extension__ struct{ cl_char s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_char4 lo, hi; }; -#endif -#if defined( __CL_CHAR2__) - __cl_char2 v2[4]; -#endif -#if defined( __CL_CHAR4__) - __cl_char4 v4[2]; -#endif -#if defined( __CL_CHAR8__ ) - __cl_char8 v8; -#endif -}cl_char8; - -typedef union -{ - cl_char CL_ALIGNED(16) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_char x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_char s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_char8 lo, hi; }; -#endif -#if defined( __CL_CHAR2__) - __cl_char2 v2[8]; -#endif -#if defined( __CL_CHAR4__) - __cl_char4 v4[4]; -#endif -#if defined( __CL_CHAR8__ ) - __cl_char8 v8[2]; -#endif -#if defined( __CL_CHAR16__ ) - __cl_char16 v16; -#endif -}cl_char16; - - -/* ---- cl_ucharn ---- */ -typedef union -{ - cl_uchar CL_ALIGNED(2) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_uchar x, y; }; - __extension__ struct{ cl_uchar s0, s1; }; - __extension__ struct{ cl_uchar lo, hi; }; -#endif -#if defined( __cl_uchar2__) - __cl_uchar2 v2; -#endif -}cl_uchar2; - -typedef union -{ - cl_uchar CL_ALIGNED(4) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_uchar x, y, z, w; }; - __extension__ struct{ cl_uchar s0, s1, s2, s3; }; - __extension__ struct{ cl_uchar2 lo, hi; }; -#endif -#if defined( __CL_UCHAR2__) - __cl_uchar2 v2[2]; -#endif -#if defined( __CL_UCHAR4__) - __cl_uchar4 v4; -#endif -}cl_uchar4; - -/* cl_uchar3 is identical in size, alignment and behavior to cl_uchar4. See section 6.1.5. */ -typedef cl_uchar4 cl_uchar3; - -typedef union -{ - cl_uchar CL_ALIGNED(8) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_uchar x, y, z, w; }; - __extension__ struct{ cl_uchar s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_uchar4 lo, hi; }; -#endif -#if defined( __CL_UCHAR2__) - __cl_uchar2 v2[4]; -#endif -#if defined( __CL_UCHAR4__) - __cl_uchar4 v4[2]; -#endif -#if defined( __CL_UCHAR8__ ) - __cl_uchar8 v8; -#endif -}cl_uchar8; - -typedef union -{ - cl_uchar CL_ALIGNED(16) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_uchar x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_uchar s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_uchar8 lo, hi; }; -#endif -#if defined( __CL_UCHAR2__) - __cl_uchar2 v2[8]; -#endif -#if defined( __CL_UCHAR4__) - __cl_uchar4 v4[4]; -#endif -#if defined( __CL_UCHAR8__ ) - __cl_uchar8 v8[2]; -#endif -#if defined( __CL_UCHAR16__ ) - __cl_uchar16 v16; -#endif -}cl_uchar16; - - -/* ---- cl_shortn ---- */ -typedef union -{ - cl_short CL_ALIGNED(4) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_short x, y; }; - __extension__ struct{ cl_short s0, s1; }; - __extension__ struct{ cl_short lo, hi; }; -#endif -#if defined( __CL_SHORT2__) - __cl_short2 v2; -#endif -}cl_short2; - -typedef union -{ - cl_short CL_ALIGNED(8) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_short x, y, z, w; }; - __extension__ struct{ cl_short s0, s1, s2, s3; }; - __extension__ struct{ cl_short2 lo, hi; }; -#endif -#if defined( __CL_SHORT2__) - __cl_short2 v2[2]; -#endif -#if defined( __CL_SHORT4__) - __cl_short4 v4; -#endif -}cl_short4; - -/* cl_short3 is identical in size, alignment and behavior to cl_short4. See section 6.1.5. */ -typedef cl_short4 cl_short3; - -typedef union -{ - cl_short CL_ALIGNED(16) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_short x, y, z, w; }; - __extension__ struct{ cl_short s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_short4 lo, hi; }; -#endif -#if defined( __CL_SHORT2__) - __cl_short2 v2[4]; -#endif -#if defined( __CL_SHORT4__) - __cl_short4 v4[2]; -#endif -#if defined( __CL_SHORT8__ ) - __cl_short8 v8; -#endif -}cl_short8; - -typedef union -{ - cl_short CL_ALIGNED(32) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_short x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_short s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_short8 lo, hi; }; -#endif -#if defined( __CL_SHORT2__) - __cl_short2 v2[8]; -#endif -#if defined( __CL_SHORT4__) - __cl_short4 v4[4]; -#endif -#if defined( __CL_SHORT8__ ) - __cl_short8 v8[2]; -#endif -#if defined( __CL_SHORT16__ ) - __cl_short16 v16; -#endif -}cl_short16; - - -/* ---- cl_ushortn ---- */ -typedef union -{ - cl_ushort CL_ALIGNED(4) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_ushort x, y; }; - __extension__ struct{ cl_ushort s0, s1; }; - __extension__ struct{ cl_ushort lo, hi; }; -#endif -#if defined( __CL_USHORT2__) - __cl_ushort2 v2; -#endif -}cl_ushort2; - -typedef union -{ - cl_ushort CL_ALIGNED(8) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_ushort x, y, z, w; }; - __extension__ struct{ cl_ushort s0, s1, s2, s3; }; - __extension__ struct{ cl_ushort2 lo, hi; }; -#endif -#if defined( __CL_USHORT2__) - __cl_ushort2 v2[2]; -#endif -#if defined( __CL_USHORT4__) - __cl_ushort4 v4; -#endif -}cl_ushort4; - -/* cl_ushort3 is identical in size, alignment and behavior to cl_ushort4. See section 6.1.5. */ -typedef cl_ushort4 cl_ushort3; - -typedef union -{ - cl_ushort CL_ALIGNED(16) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_ushort x, y, z, w; }; - __extension__ struct{ cl_ushort s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_ushort4 lo, hi; }; -#endif -#if defined( __CL_USHORT2__) - __cl_ushort2 v2[4]; -#endif -#if defined( __CL_USHORT4__) - __cl_ushort4 v4[2]; -#endif -#if defined( __CL_USHORT8__ ) - __cl_ushort8 v8; -#endif -}cl_ushort8; - -typedef union -{ - cl_ushort CL_ALIGNED(32) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_ushort x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_ushort s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_ushort8 lo, hi; }; -#endif -#if defined( __CL_USHORT2__) - __cl_ushort2 v2[8]; -#endif -#if defined( __CL_USHORT4__) - __cl_ushort4 v4[4]; -#endif -#if defined( __CL_USHORT8__ ) - __cl_ushort8 v8[2]; -#endif -#if defined( __CL_USHORT16__ ) - __cl_ushort16 v16; -#endif -}cl_ushort16; - -/* ---- cl_intn ---- */ -typedef union -{ - cl_int CL_ALIGNED(8) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_int x, y; }; - __extension__ struct{ cl_int s0, s1; }; - __extension__ struct{ cl_int lo, hi; }; -#endif -#if defined( __CL_INT2__) - __cl_int2 v2; -#endif -}cl_int2; - -typedef union -{ - cl_int CL_ALIGNED(16) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_int x, y, z, w; }; - __extension__ struct{ cl_int s0, s1, s2, s3; }; - __extension__ struct{ cl_int2 lo, hi; }; -#endif -#if defined( __CL_INT2__) - __cl_int2 v2[2]; -#endif -#if defined( __CL_INT4__) - __cl_int4 v4; -#endif -}cl_int4; - -/* cl_int3 is identical in size, alignment and behavior to cl_int4. See section 6.1.5. */ -typedef cl_int4 cl_int3; - -typedef union -{ - cl_int CL_ALIGNED(32) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_int x, y, z, w; }; - __extension__ struct{ cl_int s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_int4 lo, hi; }; -#endif -#if defined( __CL_INT2__) - __cl_int2 v2[4]; -#endif -#if defined( __CL_INT4__) - __cl_int4 v4[2]; -#endif -#if defined( __CL_INT8__ ) - __cl_int8 v8; -#endif -}cl_int8; - -typedef union -{ - cl_int CL_ALIGNED(64) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_int x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_int s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_int8 lo, hi; }; -#endif -#if defined( __CL_INT2__) - __cl_int2 v2[8]; -#endif -#if defined( __CL_INT4__) - __cl_int4 v4[4]; -#endif -#if defined( __CL_INT8__ ) - __cl_int8 v8[2]; -#endif -#if defined( __CL_INT16__ ) - __cl_int16 v16; -#endif -}cl_int16; - - -/* ---- cl_uintn ---- */ -typedef union -{ - cl_uint CL_ALIGNED(8) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_uint x, y; }; - __extension__ struct{ cl_uint s0, s1; }; - __extension__ struct{ cl_uint lo, hi; }; -#endif -#if defined( __CL_UINT2__) - __cl_uint2 v2; -#endif -}cl_uint2; - -typedef union -{ - cl_uint CL_ALIGNED(16) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_uint x, y, z, w; }; - __extension__ struct{ cl_uint s0, s1, s2, s3; }; - __extension__ struct{ cl_uint2 lo, hi; }; -#endif -#if defined( __CL_UINT2__) - __cl_uint2 v2[2]; -#endif -#if defined( __CL_UINT4__) - __cl_uint4 v4; -#endif -}cl_uint4; - -/* cl_uint3 is identical in size, alignment and behavior to cl_uint4. See section 6.1.5. */ -typedef cl_uint4 cl_uint3; - -typedef union -{ - cl_uint CL_ALIGNED(32) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_uint x, y, z, w; }; - __extension__ struct{ cl_uint s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_uint4 lo, hi; }; -#endif -#if defined( __CL_UINT2__) - __cl_uint2 v2[4]; -#endif -#if defined( __CL_UINT4__) - __cl_uint4 v4[2]; -#endif -#if defined( __CL_UINT8__ ) - __cl_uint8 v8; -#endif -}cl_uint8; - -typedef union -{ - cl_uint CL_ALIGNED(64) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_uint x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_uint s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_uint8 lo, hi; }; -#endif -#if defined( __CL_UINT2__) - __cl_uint2 v2[8]; -#endif -#if defined( __CL_UINT4__) - __cl_uint4 v4[4]; -#endif -#if defined( __CL_UINT8__ ) - __cl_uint8 v8[2]; -#endif -#if defined( __CL_UINT16__ ) - __cl_uint16 v16; -#endif -}cl_uint16; - -/* ---- cl_longn ---- */ -typedef union -{ - cl_long CL_ALIGNED(16) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_long x, y; }; - __extension__ struct{ cl_long s0, s1; }; - __extension__ struct{ cl_long lo, hi; }; -#endif -#if defined( __CL_LONG2__) - __cl_long2 v2; -#endif -}cl_long2; - -typedef union -{ - cl_long CL_ALIGNED(32) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_long x, y, z, w; }; - __extension__ struct{ cl_long s0, s1, s2, s3; }; - __extension__ struct{ cl_long2 lo, hi; }; -#endif -#if defined( __CL_LONG2__) - __cl_long2 v2[2]; -#endif -#if defined( __CL_LONG4__) - __cl_long4 v4; -#endif -}cl_long4; - -/* cl_long3 is identical in size, alignment and behavior to cl_long4. See section 6.1.5. */ -typedef cl_long4 cl_long3; - -typedef union -{ - cl_long CL_ALIGNED(64) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_long x, y, z, w; }; - __extension__ struct{ cl_long s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_long4 lo, hi; }; -#endif -#if defined( __CL_LONG2__) - __cl_long2 v2[4]; -#endif -#if defined( __CL_LONG4__) - __cl_long4 v4[2]; -#endif -#if defined( __CL_LONG8__ ) - __cl_long8 v8; -#endif -}cl_long8; - -typedef union -{ - cl_long CL_ALIGNED(128) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_long x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_long s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_long8 lo, hi; }; -#endif -#if defined( __CL_LONG2__) - __cl_long2 v2[8]; -#endif -#if defined( __CL_LONG4__) - __cl_long4 v4[4]; -#endif -#if defined( __CL_LONG8__ ) - __cl_long8 v8[2]; -#endif -#if defined( __CL_LONG16__ ) - __cl_long16 v16; -#endif -}cl_long16; - - -/* ---- cl_ulongn ---- */ -typedef union -{ - cl_ulong CL_ALIGNED(16) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_ulong x, y; }; - __extension__ struct{ cl_ulong s0, s1; }; - __extension__ struct{ cl_ulong lo, hi; }; -#endif -#if defined( __CL_ULONG2__) - __cl_ulong2 v2; -#endif -}cl_ulong2; - -typedef union -{ - cl_ulong CL_ALIGNED(32) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_ulong x, y, z, w; }; - __extension__ struct{ cl_ulong s0, s1, s2, s3; }; - __extension__ struct{ cl_ulong2 lo, hi; }; -#endif -#if defined( __CL_ULONG2__) - __cl_ulong2 v2[2]; -#endif -#if defined( __CL_ULONG4__) - __cl_ulong4 v4; -#endif -}cl_ulong4; - -/* cl_ulong3 is identical in size, alignment and behavior to cl_ulong4. See section 6.1.5. */ -typedef cl_ulong4 cl_ulong3; - -typedef union -{ - cl_ulong CL_ALIGNED(64) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_ulong x, y, z, w; }; - __extension__ struct{ cl_ulong s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_ulong4 lo, hi; }; -#endif -#if defined( __CL_ULONG2__) - __cl_ulong2 v2[4]; -#endif -#if defined( __CL_ULONG4__) - __cl_ulong4 v4[2]; -#endif -#if defined( __CL_ULONG8__ ) - __cl_ulong8 v8; -#endif -}cl_ulong8; - -typedef union -{ - cl_ulong CL_ALIGNED(128) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_ulong x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_ulong s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_ulong8 lo, hi; }; -#endif -#if defined( __CL_ULONG2__) - __cl_ulong2 v2[8]; -#endif -#if defined( __CL_ULONG4__) - __cl_ulong4 v4[4]; -#endif -#if defined( __CL_ULONG8__ ) - __cl_ulong8 v8[2]; -#endif -#if defined( __CL_ULONG16__ ) - __cl_ulong16 v16; -#endif -}cl_ulong16; - - -/* --- cl_floatn ---- */ - -typedef union -{ - cl_float CL_ALIGNED(8) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_float x, y; }; - __extension__ struct{ cl_float s0, s1; }; - __extension__ struct{ cl_float lo, hi; }; -#endif -#if defined( __CL_FLOAT2__) - __cl_float2 v2; -#endif -}cl_float2; - -typedef union -{ - cl_float CL_ALIGNED(16) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_float x, y, z, w; }; - __extension__ struct{ cl_float s0, s1, s2, s3; }; - __extension__ struct{ cl_float2 lo, hi; }; -#endif -#if defined( __CL_FLOAT2__) - __cl_float2 v2[2]; -#endif -#if defined( __CL_FLOAT4__) - __cl_float4 v4; -#endif -}cl_float4; - -/* cl_float3 is identical in size, alignment and behavior to cl_float4. See section 6.1.5. */ -typedef cl_float4 cl_float3; - -typedef union -{ - cl_float CL_ALIGNED(32) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_float x, y, z, w; }; - __extension__ struct{ cl_float s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_float4 lo, hi; }; -#endif -#if defined( __CL_FLOAT2__) - __cl_float2 v2[4]; -#endif -#if defined( __CL_FLOAT4__) - __cl_float4 v4[2]; -#endif -#if defined( __CL_FLOAT8__ ) - __cl_float8 v8; -#endif -}cl_float8; - -typedef union -{ - cl_float CL_ALIGNED(64) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_float x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_float s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_float8 lo, hi; }; -#endif -#if defined( __CL_FLOAT2__) - __cl_float2 v2[8]; -#endif -#if defined( __CL_FLOAT4__) - __cl_float4 v4[4]; -#endif -#if defined( __CL_FLOAT8__ ) - __cl_float8 v8[2]; -#endif -#if defined( __CL_FLOAT16__ ) - __cl_float16 v16; -#endif -}cl_float16; - -/* --- cl_doublen ---- */ - -typedef union -{ - cl_double CL_ALIGNED(16) s[2]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_double x, y; }; - __extension__ struct{ cl_double s0, s1; }; - __extension__ struct{ cl_double lo, hi; }; -#endif -#if defined( __CL_DOUBLE2__) - __cl_double2 v2; -#endif -}cl_double2; - -typedef union -{ - cl_double CL_ALIGNED(32) s[4]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_double x, y, z, w; }; - __extension__ struct{ cl_double s0, s1, s2, s3; }; - __extension__ struct{ cl_double2 lo, hi; }; -#endif -#if defined( __CL_DOUBLE2__) - __cl_double2 v2[2]; -#endif -#if defined( __CL_DOUBLE4__) - __cl_double4 v4; -#endif -}cl_double4; - -/* cl_double3 is identical in size, alignment and behavior to cl_double4. See section 6.1.5. */ -typedef cl_double4 cl_double3; - -typedef union -{ - cl_double CL_ALIGNED(64) s[8]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_double x, y, z, w; }; - __extension__ struct{ cl_double s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_double4 lo, hi; }; -#endif -#if defined( __CL_DOUBLE2__) - __cl_double2 v2[4]; -#endif -#if defined( __CL_DOUBLE4__) - __cl_double4 v4[2]; -#endif -#if defined( __CL_DOUBLE8__ ) - __cl_double8 v8; -#endif -}cl_double8; - -typedef union -{ - cl_double CL_ALIGNED(128) s[16]; -#if defined( __GNUC__) && ! defined( __STRICT_ANSI__ ) - __extension__ struct{ cl_double x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_double s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_double8 lo, hi; }; -#endif -#if defined( __CL_DOUBLE2__) - __cl_double2 v2[8]; -#endif -#if defined( __CL_DOUBLE4__) - __cl_double4 v4[4]; -#endif -#if defined( __CL_DOUBLE8__ ) - __cl_double8 v8[2]; -#endif -#if defined( __CL_DOUBLE16__ ) - __cl_double16 v16; -#endif -}cl_double16; - -/* Macro to facilitate debugging - * Usage: - * Place CL_PROGRAM_STRING_DEBUG_INFO on the line before the first line of your source. - * The first line ends with: CL_PROGRAM_STRING_BEGIN \" - * Each line thereafter of OpenCL C source must end with: \n\ - * The last line ends in "; - * - * Example: - * - * const char *my_program = CL_PROGRAM_STRING_BEGIN "\ - * kernel void foo( int a, float * b ) \n\ - * { \n\ - * // my comment \n\ - * *b[ get_global_id(0)] = a; \n\ - * } \n\ - * "; - * - * This should correctly set up the line, (column) and file information for your source - * string so you can do source level debugging. - */ -#define __CL_STRINGIFY( _x ) # _x -#define _CL_STRINGIFY( _x ) __CL_STRINGIFY( _x ) -#define CL_PROGRAM_STRING_DEBUG_INFO "#line " _CL_STRINGIFY(__LINE__) " \"" __FILE__ "\" \n\n" - -#ifdef __cplusplus -} -#endif - -#endif /* __CL_PLATFORM_H */ diff --git a/KEMField/opencl/1.1/CL/opencl.h b/KEMField/opencl/1.1/CL/opencl.h deleted file mode 100644 index 26a638997..000000000 --- a/KEMField/opencl/1.1/CL/opencl.h +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008-2010 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and/or associated documentation files (the - * "Materials"), to deal in the Materials without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Materials, and to - * permit persons to whom the Materials are 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 Materials. - * - * THE MATERIALS ARE 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 - * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. - ******************************************************************************/ - -/* $Revision: 11708 $ on $Date: 2010-06-13 23:36:24 -0700 (Sun, 13 Jun 2010) $ */ - -#ifndef __OPENCL_H -#define __OPENCL_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __APPLE__ - -#include -#include -#include -#include - -#else - -#include -#include -#include -#include - -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __OPENCL_H */ - diff --git a/KEMField/opencl/1.1/OpenCL/cl.hpp b/KEMField/opencl/1.1/OpenCL/cl.hpp deleted file mode 100644 index 99b86a665..000000000 --- a/KEMField/opencl/1.1/OpenCL/cl.hpp +++ /dev/null @@ -1,4011 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008-2010 The Khronos Group Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and/or associated documentation files (the - * "Materials"), to deal in the Materials without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Materials, and to - * permit persons to whom the Materials are 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 Materials. - * - * THE MATERIALS ARE 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 - * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. - ******************************************************************************/ - -/*! \file - * - * \brief C++ bindings for OpenCL 1.0 (rev 48) and OpenCL 1.1 (rev 33) - * \author Benedict R. Gaster and Laurent Morichetti - * - * Additions and fixes from Brian Cole, March 3rd 2010. - * - * \version 1.1 - * \date June 2010 - * - * Optional extension support - * - * cl - * cl_ext_device_fission - * #define USE_CL_DEVICE_FISSION - */ - -/*! \mainpage - * \section intro Introduction - * For many large applications C++ is the language of choice and so it seems - * reasonable to define C++ bindings for OpenCL. - * - * - * The interface is contained with a single C++ header file \em cl.hpp and all - * definitions are contained within the namespace \em cl. There is no additional - * requirement to include \em cl.h and to use either the C++ or original C - * bindings it is enough to simply include \em cl.hpp. - * - * The bindings themselves are lightweight and correspond closely to the - * underlying C API. Using the C++ bindings introduces no additional execution - * overhead. - * - * For detail documentation on the bindings see: - * - * The OpenCL C++ Wrapper API 1.1 (revision 04) - * http://www.khronos.org/registry/cl/specs/opencl-cplusplus-1.1.pdf - * - * \section example Example - * - * The following example shows a general use case for the C++ - * bindings, including support for the optional exception feature and - * also the supplied vector and string classes, see following sections for - * decriptions of these features. - * - * \code - * #define __CL_ENABLE_EXCEPTIONS - * - * #if defined(__APPLE__) || defined(__MACOSX) - * #include - * #else - * #include - * #endif - * #include - * #include - * #include - * - * const char * helloStr = "__kernel void " - * "hello(void) " - * "{ " - * " " - * "} "; - * - * int - * main(void) - * { - * cl_int err = CL_SUCCESS; - * try { - * - * std::vector platforms; - * cl::Platform::get(&platforms); - * if (platforms.size() == 0) { - * std::cout << "Platform size 0\n"; - * return -1; - * } - * - * cl_context_properties properties[] = - * { CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms[0])(), 0}; - * cl::Context context(CL_DEVICE_TYPE_CPU, properties); - * - * std::vector devices = context.getInfo(); - * - * cl::Program::Sources source(1, - * std::make_pair(helloStr,strlen(helloStr))); - * cl::Program program_ = cl::Program(context, source); - * program_.build(devices); - * - * cl::Kernel kernel(program_, "hello", &err); - * - * cl::Event event; - * cl::CommandQueue queue(context, devices[0], 0, &err); - * queue.enqueueNDRangeKernel( - * kernel, - * cl::NullRange, - * cl::NDRange(4,4), - * cl::NullRange, - * NULL, - * &event); - * - * event.wait(); - * } - * catch (cl::Error err) { - * std::cerr - * << "ERROR: " - * << err.what() - * << "(" - * << err.err() - * << ")" - * << std::endl; - * } - * - * return EXIT_SUCCESS; - * } - * - * \endcode - * - */ -#ifndef CL_HPP_ -#define CL_HPP_ - -#ifdef _WIN32 -#include -#include -#if defined(USE_DX_INTEROP) -#include -#endif -#endif // _WIN32 - -// -#if defined(USE_CL_DEVICE_FISSION) -#include -#endif - -#if defined(__APPLE__) || defined(__MACOSX) -#include -#include -#else -#include -#include -#endif // !__APPLE__ - -#if !defined(CL_CALLBACK) -#define CL_CALLBACK -#endif //CL_CALLBACK - -#include - -#if !defined(__NO_STD_VECTOR) -#include -#endif - -#if !defined(__NO_STD_STRING) -#include -#endif - -#if defined(linux) || defined(__APPLE__) || defined(__MACOSX) -# include -#endif // linux - -#include - -/*! \namespace cl - * - * \brief The OpenCL C++ bindings are defined within this namespace. - * - */ -namespace cl { - -#define __INIT_CL_EXT_FCN_PTR(name) \ - if(!pfn_##name) { \ - pfn_##name = (PFN_##name) \ - clGetExtensionFunctionAddress(#name); \ - if(!pfn_##name) { \ - } \ - } - -class Program; -class Device; -class Context; -class CommandQueue; -class Memory; - -#if defined(__CL_ENABLE_EXCEPTIONS) -#include -/*! \class Error - * \brief Exception class - */ -class Error : public std::exception -{ -private: - cl_int err_; - const char * errStr_; -public: - /*! Create a new CL error exception for a given error code - * and corresponding message. - */ - Error(cl_int err, const char * errStr = NULL) : err_(err), errStr_(errStr) - {} - - ~Error() throw() {} - - /*! \brief Get error string associated with exception - * - * \return A memory pointer to the error message string. - */ - virtual const char * what() const throw () - { - if (errStr_ == NULL) { - return "empty"; - } - else { - return errStr_; - } - } - - /*! \brief Get error code associated with exception - * - * \return The error code. - */ - const cl_int err(void) const { return err_; } -}; - -#define __ERR_STR(x) #x -#else -#define __ERR_STR(x) NULL -#endif // __CL_ENABLE_EXCEPTIONS - -//! \cond DOXYGEN_DETAIL -#if !defined(__CL_USER_OVERRIDE_ERROR_STRINGS) -#define __GET_DEVICE_INFO_ERR __ERR_STR(clgetDeviceInfo) -#define __GET_PLATFORM_INFO_ERR __ERR_STR(clGetPlatformInfo) -#define __GET_DEVICE_IDS_ERR __ERR_STR(clGetDeviceIDs) -#define __GET_PLATFORM_IDS_ERR __ERR_STR(clGetPlatformIDs) -#define __GET_CONTEXT_INFO_ERR __ERR_STR(clGetContextInfo) -#define __GET_EVENT_INFO_ERR __ERR_STR(clGetEventInfo) -#define __GET_EVENT_PROFILE_INFO_ERR __ERR_STR(clGetEventProfileInfo) -#define __GET_MEM_OBJECT_INFO_ERR __ERR_STR(clGetMemObjectInfo) -#define __GET_IMAGE_INFO_ERR __ERR_STR(clGetImageInfo) -#define __GET_SAMPLER_INFO_ERR __ERR_STR(clGetSamplerInfo) -#define __GET_KERNEL_INFO_ERR __ERR_STR(clGetKernelInfo) -#define __GET_KERNEL_WORK_GROUP_INFO_ERR __ERR_STR(clGetKernelWorkGroupInfo) -#define __GET_PROGRAM_INFO_ERR __ERR_STR(clGetProgramInfo) -#define __GET_PROGRAM_BUILD_INFO_ERR __ERR_STR(clGetProgramBuildInfo) -#define __GET_COMMAND_QUEUE_INFO_ERR __ERR_STR(clGetCommandQueueInfo) - -#define __CREATE_CONTEXT_FROM_TYPE_ERR __ERR_STR(clCreateContextFromType) -#define __GET_SUPPORTED_IMAGE_FORMATS_ERR __ERR_STR(clGetSupportedImageFormats) - -#define __CREATE_BUFFER_ERR __ERR_STR(clCreateBuffer) -#define __CREATE_SUBBUFFER_ERR __ERR_STR(clCreateSubBuffer) -#define __CREATE_GL_BUFFER_ERR __ERR_STR(clCreateFromGLBuffer) -#define __GET_GL_OBJECT_INFO_ERR __ERR_STR(clGetGLObjectInfo) -#define __CREATE_IMAGE2D_ERR __ERR_STR(clCreateImage2D) -#define __CREATE_IMAGE3D_ERR __ERR_STR(clCreateImage3D) -#define __CREATE_SAMPLER_ERR __ERR_STR(clCreateSampler) -#define __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR __ERR_STR(clSetMemObjectDestructorCallback) - -#define __CREATE_USER_EVENT_ERR __ERR_STR(clCreateUserEvent) -#define __SET_USER_EVENT_STATUS_ERR __ERR_STR(clSetUserEventStatus) -#define __SET_EVENT_CALLBACK_ERR __ERR_STR(clSetEventCallback) -#define __WAIT_FOR_EVENTS_ERR __ERR_STR(clWaitForEvents) - -#define __CREATE_KERNEL_ERR __ERR_STR(clCreateKernel) -#define __SET_KERNEL_ARGS_ERR __ERR_STR(clSetKernelArg) -#define __CREATE_PROGRAM_WITH_SOURCE_ERR __ERR_STR(clCreateProgramWithSource) -#define __CREATE_PROGRAM_WITH_BINARY_ERR __ERR_STR(clCreateProgramWithBinary) -#define __BUILD_PROGRAM_ERR __ERR_STR(clBuildProgram) -#define __CREATE_KERNELS_IN_PROGRAM_ERR __ERR_STR(clCreateKernelsInProgram) - -#define __CREATE_COMMAND_QUEUE_ERR __ERR_STR(clCreateCommandQueue) -#define __SET_COMMAND_QUEUE_PROPERTY_ERR __ERR_STR(clSetCommandQueueProperty) -#define __ENQUEUE_READ_BUFFER_ERR __ERR_STR(clEnqueueReadBuffer) -#define __ENQUEUE_READ_BUFFER_RECT_ERR __ERR_STR(clEnqueueReadBufferRect) -#define __ENQUEUE_WRITE_BUFFER_ERR __ERR_STR(clEnqueueWriteBuffer) -#define __ENQUEUE_WRITE_BUFFER_RECT_ERR __ERR_STR(clEnqueueWriteBufferRect) -#define __ENQEUE_COPY_BUFFER_ERR __ERR_STR(clEnqueueCopyBuffer) -#define __ENQEUE_COPY_BUFFER_RECT_ERR __ERR_STR(clEnqueueCopyBufferRect) -#define __ENQUEUE_READ_IMAGE_ERR __ERR_STR(clEnqueueReadImage) -#define __ENQUEUE_WRITE_IMAGE_ERR __ERR_STR(clEnqueueWriteImage) -#define __ENQUEUE_COPY_IMAGE_ERR __ERR_STR(clEnqueueCopyImage) -#define __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR __ERR_STR(clEnqueueCopyImageToBuffer) -#define __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR __ERR_STR(clEnqueueCopyBufferToImage) -#define __ENQUEUE_MAP_BUFFER_ERR __ERR_STR(clEnqueueMapBuffer) -#define __ENQUEUE_MAP_IMAGE_ERR __ERR_STR(clEnqueueMapImage) -#define __ENQUEUE_UNMAP_MEM_OBJECT_ERR __ERR_STR(clEnqueueUnMapMemObject) -#define __ENQUEUE_NDRANGE_KERNEL_ERR __ERR_STR(clEnqueueNDRangeKernel) -#define __ENQUEUE_TASK_ERR __ERR_STR(clEnqueueTask) -#define __ENQUEUE_NATIVE_KERNEL __ERR_STR(clEnqueueNativeKernel) -#define __ENQUEUE_MARKER_ERR __ERR_STR(clEnqueueMarker) -#define __ENQUEUE_WAIT_FOR_EVENTS_ERR __ERR_STR(clEnqueueWaitForEvents) -#define __ENQUEUE_BARRIER_ERR __ERR_STR(clEnqueueBarrier) - -#define __ENQUEUE_ACQUIRE_GL_ERR __ERR_STR(clEnqueueAcquireGLObjects) -#define __ENQUEUE_RELEASE_GL_ERR __ERR_STR(clEnqueueReleaseGLObjects) - -#define __UNLOAD_COMPILER_ERR __ERR_STR(clUnloadCompiler) - -#define __FLUSH_ERR __ERR_STR(clFlush) -#define __FINISH_ERR __ERR_STR(clFinish) - -#define __CREATE_SUB_DEVICES __ERR_STR(clCreateSubDevicesEXT) -#endif // __CL_USER_OVERRIDE_ERROR_STRINGS -//! \endcond - -/*! \class string - * \brief Simple string class, that provides a limited subset of std::string - * functionality but avoids many of the issues that come with that class. - */ -class string -{ -private: - ::size_t size_; - char * str_; -public: - string(void) : size_(0), str_(NULL) - { - } - - string(char * str, ::size_t size) : - size_(size), - str_(NULL) - { - str_ = new char[size_+1]; - if (str_ != NULL) { - memcpy(str_, str, size_ * sizeof(char)); - str_[size_] = '\0'; - } - else { - size_ = 0; - } - } - - string(char * str) : - str_(NULL) - { - size_= ::strlen(str); - str_ = new char[size_ + 1]; - if (str_ != NULL) { - memcpy(str_, str, (size_ + 1) * sizeof(char)); - } - else { - size_ = 0; - } - } - - string& operator=(const string& rhs) - { - if (this == &rhs) { - return *this; - } - - if (rhs.size_ == 0 || rhs.str_ == NULL) { - size_ = 0; - str_ = NULL; - } - else { - size_ = rhs.size_; - str_ = new char[size_ + 1]; - if (str_ != NULL) { - memcpy(str_, rhs.str_, (size_ + 1) * sizeof(char)); - } - else { - size_ = 0; - } - } - - return *this; - } - - string(const string& rhs) - { - *this = rhs; - } - - ~string() - { - if (str_ != NULL) { - delete[] str_; - } - } - - ::size_t size(void) const { return size_; } - ::size_t length(void) const { return size(); } - - const char * c_str(void) const { return (str_) ? str_ : "";} -}; - -#if !defined(__USE_DEV_STRING) && !defined(__NO_STD_STRING) -#include -typedef std::string STRING_CLASS; -#elif !defined(__USE_DEV_STRING) -typedef cl::string STRING_CLASS; -#endif - -#if !defined(__USE_DEV_VECTOR) && !defined(__NO_STD_VECTOR) -#include -#define VECTOR_CLASS std::vector -#elif !defined(__USE_DEV_VECTOR) -#define VECTOR_CLASS cl::vector -#endif - -#if !defined(__MAX_DEFAULT_VECTOR_SIZE) -#define __MAX_DEFAULT_VECTOR_SIZE 10 -#endif - -/*! \class vector - * \brief Fixed sized vector implementation that mirroring - * std::vector functionality. - */ -template -class vector -{ -private: - T data_[N]; - unsigned int size_; - bool empty_; -public: - vector() : - size_(-1), - empty_(true) - {} - - ~vector() {} - - unsigned int size(void) const - { - return size_ + 1; - } - - void clear() - { - size_ = -1; - empty_ = true; - } - - void push_back (const T& x) - { - if (size() < N) { - size_++; - data_[size_] = x; - empty_ = false; - } - } - - void pop_back(void) - { - if (!empty_) { - data_[size_].~T(); - size_--; - if (size_ == -1) { - empty_ = true; - } - } - } - - vector(const vector& vec) : - size_(vec.size_), - empty_(vec.empty_) - { - if (!empty_) { - memcpy(&data_[0], &vec.data_[0], size() * sizeof(T)); - } - } - - vector(unsigned int size, const T& val = T()) : - size_(-1), - empty_(true) - { - for (unsigned int i = 0; i < size; i++) { - push_back(val); - } - } - - vector& operator=(const vector& rhs) - { - if (this == &rhs) { - return *this; - } - - size_ = rhs.size_; - empty_ = rhs.empty_; - - if (!empty_) { - memcpy(&data_[0], &rhs.data_[0], size() * sizeof(T)); - } - - return *this; - } - - bool operator==(vector &vec) - { - if (empty_ && vec.empty_) { - return true; - } - - if (size() != vec.size()) { - return false; - } - - return memcmp(&data_[0], &vec.data_[0], size() * sizeof(T)) == 0 ? true : false; - } - - operator T* () { return data_; } - operator const T* () const { return data_; } - - bool empty (void) const - { - return empty_; - } - - unsigned int max_size (void) const - { - return N; - } - - unsigned int capacity () const - { - return sizeof(T) * N; - } - - T& operator[](int index) - { - return data_[index]; - } - - T operator[](int index) const - { - return data_[index]; - } - - template - void assign(I start, I end) - { - clear(); - while(start < end) { - push_back(*start); - start++; - } - } - - /*! \class iterator - * \brief Iterator class for vectors - */ - class iterator - { - private: - vector vec_; - int index_; - bool initialized_; - public: - iterator(void) : - index_(-1), - initialized_(false) - { - index_ = -1; - initialized_ = false; - } - - ~iterator(void) {} - - static iterator begin(vector &vec) - { - iterator i; - - if (!vec.empty()) { - i.index_ = 0; - } - - i.vec_ = vec; - i.initialized_ = true; - return i; - } - - static iterator end(vector &vec) - { - iterator i; - - if (!vec.empty()) { - i.index_ = vec.size(); - } - i.vec_ = vec; - i.initialized_ = true; - return i; - } - - bool operator==(iterator i) - { - return ((vec_ == i.vec_) && - (index_ == i.index_) && - (initialized_ == i.initialized_)); - } - - bool operator!=(iterator i) - { - return (!(*this==i)); - } - - void operator++() - { - index_++; - } - - void operator++(int x) - { - index_ += x; - } - - void operator--() - { - index_--; - } - - void operator--(int x) - { - index_ -= x; - } - - T operator *() - { - return vec_[index_]; - } - }; - - iterator begin(void) - { - return iterator::begin(*this); - } - - iterator end(void) - { - return iterator::end(*this); - } - - T& front(void) - { - return data_[0]; - } - - T& back(void) - { - return data_[size_]; - } - - const T& front(void) const - { - return data_[0]; - } - - const T& back(void) const - { - return data_[size_]; - } -}; - -/*! - * \brief size_t class used to interface between C++ and - * OpenCL C calls that require arrays of size_t values, who's - * size is known statically. - */ -template -struct size_t : public cl::vector< ::size_t, N> { }; - -namespace detail { - -// GetInfo help struct -template -struct GetInfoHelper -{ - static cl_int - get(Functor f, cl_uint name, T* param) - { - return f(name, sizeof(T), param, NULL); - } -}; - -// Specialized GetInfoHelper for VECTOR_CLASS params -template -struct GetInfoHelper > -{ - static cl_int get(Func f, cl_uint name, VECTOR_CLASS* param) - { - ::size_t required; - cl_int err = f(name, 0, NULL, &required); - if (err != CL_SUCCESS) { - return err; - } - - T* value = (T*) alloca(required); - err = f(name, required, value, NULL); - if (err != CL_SUCCESS) { - return err; - } - - param->assign(&value[0], &value[required/sizeof(T)]); - return CL_SUCCESS; - } -}; - -// Specialized for getInfo -template -struct GetInfoHelper > -{ - static cl_int - get(Func f, cl_uint name, VECTOR_CLASS* param) - { - cl_uint err = f(name, param->size() * sizeof(char *), &(*param)[0], NULL); - if (err != CL_SUCCESS) { - return err; - } - - return CL_SUCCESS; - } -}; - -// Specialized GetInfoHelper for STRING_CLASS params -template -struct GetInfoHelper -{ - static cl_int get(Func f, cl_uint name, STRING_CLASS* param) - { - ::size_t required; - cl_int err = f(name, 0, NULL, &required); - if (err != CL_SUCCESS) { - return err; - } - - char* value = (char*) alloca(required); - err = f(name, required, value, NULL); - if (err != CL_SUCCESS) { - return err; - } - - *param = value; - return CL_SUCCESS; - } -}; - -#define __GET_INFO_HELPER_WITH_RETAIN(CPP_TYPE) \ -namespace detail { \ -template \ -struct GetInfoHelper \ -{ \ - static cl_int get(Func f, cl_uint name, CPP_TYPE* param) \ - { \ - cl_uint err = f(name, sizeof(CPP_TYPE), param, NULL); \ - if (err != CL_SUCCESS) { \ - return err; \ - } \ - \ - return ReferenceHandler::retain((*param)()); \ - } \ -}; \ -} - - -#define __PARAM_NAME_INFO_1_0(F) \ - F(cl_platform_info, CL_PLATFORM_PROFILE, STRING_CLASS) \ - F(cl_platform_info, CL_PLATFORM_VERSION, STRING_CLASS) \ - F(cl_platform_info, CL_PLATFORM_NAME, STRING_CLASS) \ - F(cl_platform_info, CL_PLATFORM_VENDOR, STRING_CLASS) \ - F(cl_platform_info, CL_PLATFORM_EXTENSIONS, STRING_CLASS) \ - \ - F(cl_device_info, CL_DEVICE_TYPE, cl_device_type) \ - F(cl_device_info, CL_DEVICE_VENDOR_ID, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_WORK_GROUP_SIZE, ::size_t) \ - F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_SIZES, VECTOR_CLASS< ::size_t>) \ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, cl_uint) \ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, cl_uint) \ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, cl_uint) \ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, cl_uint) \ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, cl_uint) \ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint) \ - F(cl_device_info, CL_DEVICE_ADDRESS_BITS, cl_bitfield) \ - F(cl_device_info, CL_DEVICE_MAX_READ_IMAGE_ARGS, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_MEM_ALLOC_SIZE, cl_ulong) \ - F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_WIDTH, ::size_t) \ - F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_HEIGHT, ::size_t) \ - F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_WIDTH, ::size_t) \ - F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_HEIGHT, ::size_t) \ - F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_DEPTH, ::size_t) \ - F(cl_device_info, CL_DEVICE_IMAGE_SUPPORT, cl_uint) \ - F(cl_device_info, CL_DEVICE_MAX_PARAMETER_SIZE, ::size_t) \ - F(cl_device_info, CL_DEVICE_MAX_SAMPLERS, cl_uint) \ - F(cl_device_info, CL_DEVICE_MEM_BASE_ADDR_ALIGN, cl_uint) \ - F(cl_device_info, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, cl_uint) \ - F(cl_device_info, CL_DEVICE_SINGLE_FP_CONFIG, cl_device_fp_config) \ - F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, cl_device_mem_cache_type) \ - F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, cl_uint)\ - F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, cl_ulong) \ - F(cl_device_info, CL_DEVICE_GLOBAL_MEM_SIZE, cl_ulong) \ - F(cl_device_info, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, cl_ulong) \ - F(cl_device_info, CL_DEVICE_MAX_CONSTANT_ARGS, cl_uint) \ - F(cl_device_info, CL_DEVICE_LOCAL_MEM_TYPE, cl_device_local_mem_type) \ - F(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE, cl_ulong) \ - F(cl_device_info, CL_DEVICE_ERROR_CORRECTION_SUPPORT, cl_bool) \ - F(cl_device_info, CL_DEVICE_PROFILING_TIMER_RESOLUTION, ::size_t) \ - F(cl_device_info, CL_DEVICE_ENDIAN_LITTLE, cl_bool) \ - F(cl_device_info, CL_DEVICE_AVAILABLE, cl_bool) \ - F(cl_device_info, CL_DEVICE_COMPILER_AVAILABLE, cl_bool) \ - F(cl_device_info, CL_DEVICE_EXECUTION_CAPABILITIES, cl_device_exec_capabilities) \ - F(cl_device_info, CL_DEVICE_QUEUE_PROPERTIES, cl_command_queue_properties) \ - F(cl_device_info, CL_DEVICE_PLATFORM, cl_platform_id) \ - F(cl_device_info, CL_DEVICE_NAME, STRING_CLASS) \ - F(cl_device_info, CL_DEVICE_VENDOR, STRING_CLASS) \ - F(cl_device_info, CL_DRIVER_VERSION, STRING_CLASS) \ - F(cl_device_info, CL_DEVICE_PROFILE, STRING_CLASS) \ - F(cl_device_info, CL_DEVICE_VERSION, STRING_CLASS) \ - F(cl_device_info, CL_DEVICE_EXTENSIONS, STRING_CLASS) \ - \ - F(cl_context_info, CL_CONTEXT_REFERENCE_COUNT, cl_uint) \ - F(cl_context_info, CL_CONTEXT_DEVICES, VECTOR_CLASS) \ - F(cl_context_info, CL_CONTEXT_PROPERTIES, VECTOR_CLASS) \ - \ - F(cl_event_info, CL_EVENT_COMMAND_QUEUE, cl::CommandQueue) \ - F(cl_event_info, CL_EVENT_COMMAND_TYPE, cl_command_type) \ - F(cl_event_info, CL_EVENT_REFERENCE_COUNT, cl_uint) \ - F(cl_event_info, CL_EVENT_COMMAND_EXECUTION_STATUS, cl_uint) \ - \ - F(cl_profiling_info, CL_PROFILING_COMMAND_QUEUED, cl_ulong) \ - F(cl_profiling_info, CL_PROFILING_COMMAND_SUBMIT, cl_ulong) \ - F(cl_profiling_info, CL_PROFILING_COMMAND_START, cl_ulong) \ - F(cl_profiling_info, CL_PROFILING_COMMAND_END, cl_ulong) \ - \ - F(cl_mem_info, CL_MEM_TYPE, cl_mem_object_type) \ - F(cl_mem_info, CL_MEM_FLAGS, cl_mem_flags) \ - F(cl_mem_info, CL_MEM_SIZE, ::size_t) \ - F(cl_mem_info, CL_MEM_HOST_PTR, void*) \ - F(cl_mem_info, CL_MEM_MAP_COUNT, cl_uint) \ - F(cl_mem_info, CL_MEM_REFERENCE_COUNT, cl_uint) \ - F(cl_mem_info, CL_MEM_CONTEXT, cl::Context) \ - \ - F(cl_image_info, CL_IMAGE_FORMAT, cl_image_format) \ - F(cl_image_info, CL_IMAGE_ELEMENT_SIZE, ::size_t) \ - F(cl_image_info, CL_IMAGE_ROW_PITCH, ::size_t) \ - F(cl_image_info, CL_IMAGE_SLICE_PITCH, ::size_t) \ - F(cl_image_info, CL_IMAGE_WIDTH, ::size_t) \ - F(cl_image_info, CL_IMAGE_HEIGHT, ::size_t) \ - F(cl_image_info, CL_IMAGE_DEPTH, ::size_t) \ - \ - F(cl_sampler_info, CL_SAMPLER_REFERENCE_COUNT, cl_uint) \ - F(cl_sampler_info, CL_SAMPLER_CONTEXT, cl::Context) \ - F(cl_sampler_info, CL_SAMPLER_NORMALIZED_COORDS, cl_addressing_mode) \ - F(cl_sampler_info, CL_SAMPLER_ADDRESSING_MODE, cl_filter_mode) \ - F(cl_sampler_info, CL_SAMPLER_FILTER_MODE, cl_bool) \ - \ - F(cl_program_info, CL_PROGRAM_REFERENCE_COUNT, cl_uint) \ - F(cl_program_info, CL_PROGRAM_CONTEXT, cl::Context) \ - F(cl_program_info, CL_PROGRAM_NUM_DEVICES, cl_uint) \ - F(cl_program_info, CL_PROGRAM_DEVICES, VECTOR_CLASS) \ - F(cl_program_info, CL_PROGRAM_SOURCE, STRING_CLASS) \ - F(cl_program_info, CL_PROGRAM_BINARY_SIZES, VECTOR_CLASS< ::size_t>) \ - F(cl_program_info, CL_PROGRAM_BINARIES, VECTOR_CLASS) \ - \ - F(cl_program_build_info, CL_PROGRAM_BUILD_STATUS, cl_build_status) \ - F(cl_program_build_info, CL_PROGRAM_BUILD_OPTIONS, STRING_CLASS) \ - F(cl_program_build_info, CL_PROGRAM_BUILD_LOG, STRING_CLASS) \ - \ - F(cl_kernel_info, CL_KERNEL_FUNCTION_NAME, STRING_CLASS) \ - F(cl_kernel_info, CL_KERNEL_NUM_ARGS, cl_uint) \ - F(cl_kernel_info, CL_KERNEL_REFERENCE_COUNT, cl_uint) \ - F(cl_kernel_info, CL_KERNEL_CONTEXT, cl::Context) \ - F(cl_kernel_info, CL_KERNEL_PROGRAM, cl::Program) \ - \ - F(cl_kernel_work_group_info, CL_KERNEL_WORK_GROUP_SIZE, ::size_t) \ - F(cl_kernel_work_group_info, CL_KERNEL_COMPILE_WORK_GROUP_SIZE, cl::size_t<3>) \ - F(cl_kernel_work_group_info, CL_KERNEL_LOCAL_MEM_SIZE, cl_ulong) \ - \ - F(cl_command_queue_info, CL_QUEUE_CONTEXT, cl::Context) \ - F(cl_command_queue_info, CL_QUEUE_DEVICE, cl::Device) \ - F(cl_command_queue_info, CL_QUEUE_REFERENCE_COUNT, cl_uint) \ - F(cl_command_queue_info, CL_QUEUE_PROPERTIES, cl_command_queue_properties) - -#if defined(CL_VERSION_1_1) -#define __PARAM_NAME_INFO_1_1(F) \ - F(cl_context_info, CL_CONTEXT_NUM_DEVICES, cl_uint)\ - F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_INT, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE, cl_uint) \ - F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF, cl_uint) \ - F(cl_device_info, CL_DEVICE_DOUBLE_FP_CONFIG, cl_device_fp_config) \ - F(cl_device_info, CL_DEVICE_HALF_FP_CONFIG, cl_device_fp_config) \ - F(cl_device_info, CL_DEVICE_HOST_UNIFIED_MEMORY, cl_bool) \ - \ - F(cl_mem_info, CL_MEM_ASSOCIATED_MEMOBJECT, cl::Memory) \ - F(cl_mem_info, CL_MEM_OFFSET, ::size_t) \ - \ - F(cl_kernel_work_group_info, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, ::size_t) \ - F(cl_kernel_work_group_info, CL_KERNEL_PRIVATE_MEM_SIZE, cl_ulong) \ - \ - F(cl_event_info, CL_EVENT_CONTEXT, cl::Context) -#endif // CL_VERSION_1_1 - -#if defined(USE_CL_DEVICE_FISSION) -#define __PARAM_NAME_DEVICE_FISSION(F) \ - F(cl_device_info, CL_DEVICE_PARENT_DEVICE_EXT, cl_device_id) \ - F(cl_device_info, CL_DEVICE_PARTITION_TYPES_EXT, VECTOR_CLASS) \ - F(cl_device_info, CL_DEVICE_AFFINITY_DOMAINS_EXT, VECTOR_CLASS) \ - F(cl_device_info, CL_DEVICE_REFERENCE_COUNT_EXT , cl_uint) \ - F(cl_device_info, CL_DEVICE_PARTITION_STYLE_EXT, VECTOR_CLASS) -#endif // USE_CL_DEVICE_FISSION - -template -struct param_traits {}; - -#define __DECLARE_PARAM_TRAITS(token, param_name, T) \ -struct token; \ -template<> \ -struct param_traits \ -{ \ - enum { value = param_name }; \ - typedef T param_type; \ -}; - -__PARAM_NAME_INFO_1_0(__DECLARE_PARAM_TRAITS); -#if defined(CL_VERSION_1_1) -__PARAM_NAME_INFO_1_1(__DECLARE_PARAM_TRAITS); -#endif // CL_VERSION_1_1 - -#if defined(USE_CL_DEVICE_FISSION) -__PARAM_NAME_DEVICE_FISSION(__DECLARE_PARAM_TRAITS); -#endif // USE_CL_DEVICE_FISSION - -#undef __DECLARE_PARAM_TRAITS - -// Convenience functions - -template -inline cl_int -getInfo(Func f, cl_uint name, T* param) -{ - return GetInfoHelper::get(f, name, param); -} - -template -struct GetInfoFunctor0 -{ - Func f_; const Arg0& arg0_; - cl_int operator ()( - cl_uint param, ::size_t size, void* value, ::size_t* size_ret) - { return f_(arg0_, param, size, value, size_ret); } -}; - -template -struct GetInfoFunctor1 -{ - Func f_; const Arg0& arg0_; const Arg1& arg1_; - cl_int operator ()( - cl_uint param, ::size_t size, void* value, ::size_t* size_ret) - { return f_(arg0_, arg1_, param, size, value, size_ret); } -}; - -template -inline cl_int -getInfo(Func f, const Arg0& arg0, cl_uint name, T* param) -{ - GetInfoFunctor0 f0 = { f, arg0 }; - return GetInfoHelper, T> - ::get(f0, name, param); -} - -template -inline cl_int -getInfo(Func f, const Arg0& arg0, const Arg1& arg1, cl_uint name, T* param) -{ - GetInfoFunctor1 f0 = { f, arg0, arg1 }; - return GetInfoHelper, T> - ::get(f0, name, param); -} - -template -struct ReferenceHandler -{ }; - -template <> -struct ReferenceHandler -{ - // cl_device_id does not have retain(). - static cl_int retain(cl_device_id) - { return CL_INVALID_DEVICE; } - // cl_device_id does not have release(). - static cl_int release(cl_device_id) - { return CL_INVALID_DEVICE; } -}; - -template <> -struct ReferenceHandler -{ - // cl_platform_id does not have retain(). - static cl_int retain(cl_platform_id) - { return CL_INVALID_PLATFORM; } - // cl_platform_id does not have release(). - static cl_int release(cl_platform_id) - { return CL_INVALID_PLATFORM; } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_context context) - { return ::clRetainContext(context); } - static cl_int release(cl_context context) - { return ::clReleaseContext(context); } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_command_queue queue) - { return ::clRetainCommandQueue(queue); } - static cl_int release(cl_command_queue queue) - { return ::clReleaseCommandQueue(queue); } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_mem memory) - { return ::clRetainMemObject(memory); } - static cl_int release(cl_mem memory) - { return ::clReleaseMemObject(memory); } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_sampler sampler) - { return ::clRetainSampler(sampler); } - static cl_int release(cl_sampler sampler) - { return ::clReleaseSampler(sampler); } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_program program) - { return ::clRetainProgram(program); } - static cl_int release(cl_program program) - { return ::clReleaseProgram(program); } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_kernel kernel) - { return ::clRetainKernel(kernel); } - static cl_int release(cl_kernel kernel) - { return ::clReleaseKernel(kernel); } -}; - -template <> -struct ReferenceHandler -{ - static cl_int retain(cl_event event) - { return ::clRetainEvent(event); } - static cl_int release(cl_event event) - { return ::clReleaseEvent(event); } -}; - -template -class Wrapper -{ -public: - typedef T cl_type; - -protected: - cl_type object_; - -public: - Wrapper() : object_(NULL) { } - - ~Wrapper() - { - if (object_ != NULL) { release(); } - } - - Wrapper(const Wrapper& rhs) - { - object_ = rhs.object_; - if (object_ != NULL) { retain(); } - } - - Wrapper& operator = (const Wrapper& rhs) - { - if (object_ != NULL) { release(); } - object_ = rhs.object_; - if (object_ != NULL) { retain(); } - return *this; - } - - cl_type operator ()() const { return object_; } - - cl_type& operator ()() { return object_; } - -protected: - - cl_int retain() const - { - return ReferenceHandler::retain(object_); - } - - cl_int release() const - { - return ReferenceHandler::release(object_); - } -}; - -#if defined(__CL_ENABLE_EXCEPTIONS) -static inline cl_int errHandler ( - cl_int err, - const char * errStr = NULL) throw(Error) -{ - if (err != CL_SUCCESS) { - throw Error(err, errStr); - } - return err; -} -#else -static inline cl_int errHandler (cl_int err, const char * errStr = NULL) -{ - return err; -} -#endif // __CL_ENABLE_EXCEPTIONS - -} // namespace detail -//! \endcond - -/*! \stuct ImageFormat - * \brief ImageFormat interface fro cl_image_format. - */ -struct ImageFormat : public cl_image_format -{ - ImageFormat(){} - - ImageFormat(cl_channel_order order, cl_channel_type type) - { - image_channel_order = order; - image_channel_data_type = type; - } - - ImageFormat& operator = (const ImageFormat& rhs) - { - if (this != &rhs) { - this->image_channel_data_type = rhs.image_channel_data_type; - this->image_channel_order = rhs.image_channel_order; - } - return *this; - } -}; - -/*! \class Device - * \brief Device interface for cl_device_id. - */ -class Device : public detail::Wrapper -{ -public: - Device(cl_device_id device) { object_ = device; } - - Device() : detail::Wrapper() { } - - Device(const Device& device) : detail::Wrapper(device) { } - - Device& operator = (const Device& rhs) - { - if (this != &rhs) { - detail::Wrapper::operator=(rhs); - } - return *this; - } - - template - cl_int getInfo(cl_device_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetDeviceInfo, object_, name, param), - __GET_DEVICE_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_device_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - -#if defined(USE_CL_DEVICE_FISSION) - cl_int createSubDevices( - const cl_device_partition_property_ext * properties, - VECTOR_CLASS* devices) - { - typedef CL_API_ENTRY cl_int - ( CL_API_CALL * PFN_clCreateSubDevicesEXT)( - cl_device_id /*in_device*/, - const cl_device_partition_property_ext * /* properties */, - cl_uint /*num_entries*/, - cl_device_id * /*out_devices*/, - cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1; - - static PFN_clCreateSubDevicesEXT pfn_clCreateSubDevicesEXT = NULL; - __INIT_CL_EXT_FCN_PTR(clCreateSubDevicesEXT); - - cl_uint n = 0; - cl_int err = pfn_clCreateSubDevicesEXT(object_, properties, 0, NULL, &n); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __CREATE_SUB_DEVICES); - } - - cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id)); - err = pfn_clCreateSubDevicesEXT(object_, properties, n, ids, NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __CREATE_SUB_DEVICES); - } - - devices->assign(&ids[0], &ids[n]); - return CL_SUCCESS; - } -#endif -}; - -/*! \class Platform - * \brief Platform interface. - */ -class Platform : public detail::Wrapper -{ -public: - static const Platform null(); - - Platform(cl_platform_id platform) { object_ = platform; } - - Platform() : detail::Wrapper() { } - - Platform(const Platform& platform) : detail::Wrapper(platform) { } - - Platform& operator = (const Platform& rhs) - { - if (this != &rhs) { - detail::Wrapper::operator=(rhs); - } - return *this; - } - - cl_int getInfo(cl_platform_info name, STRING_CLASS* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetPlatformInfo, object_, name, param), - __GET_PLATFORM_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_platform_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - cl_int getDevices( - cl_device_type type, - VECTOR_CLASS* devices) const - { - cl_uint n = 0; - cl_int err = ::clGetDeviceIDs(object_, type, 0, NULL, &n); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_DEVICE_IDS_ERR); - } - - cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id)); - err = ::clGetDeviceIDs(object_, type, n, ids, NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_DEVICE_IDS_ERR); - } - - devices->assign(&ids[0], &ids[n]); - return CL_SUCCESS; - } - -#if defined(USE_DX_INTEROP) - /*! \brief Get the list of available D3D10 devices. - * - * \param d3d_device_source. - * - * \param d3d_object. - * - * \param d3d_device_set. - * - * \param devices returns a vector of OpenCL D3D10 devices found. The cl::Device - * values returned in devices can be used to identify a specific OpenCL - * device. If \a devices argument is NULL, this argument is ignored. - * - * \return One of the following values: - * - CL_SUCCESS if the function is executed successfully. - * - * The application can query specific capabilities of the OpenCL device(s) - * returned by cl::getDevices. This can be used by the application to - * determine which device(s) to use. - * - * \note In the case that exceptions are enabled and a return value - * other than CL_SUCCESS is generated, then cl::Error exception is - * generated. - */ - cl_int getDevices( - cl_d3d10_device_source_khr d3d_device_source, - void * d3d_object, - cl_d3d10_device_set_khr d3d_device_set, - VECTOR_CLASS* devices) const - { - typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clGetDeviceIDsFromD3D10KHR)( - cl_platform_id platform, - cl_d3d10_device_source_khr d3d_device_source, - void * d3d_object, - cl_d3d10_device_set_khr d3d_device_set, - cl_uint num_entries, - cl_device_id * devices, - cl_uint* num_devices); - - static PFN_clGetDeviceIDsFromD3D10KHR pfn_clGetDeviceIDsFromD3D10KHR = NULL; - __INIT_CL_EXT_FCN_PTR(clGetDeviceIDsFromD3D10KHR); - - cl_uint n = 0; - cl_int err = pfn_clGetDeviceIDsFromD3D10KHR( - object_, - d3d_device_source, - d3d_object, - d3d_device_set, - 0, - NULL, - &n); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_DEVICE_IDS_ERR); - } - - cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id)); - err = pfn_clGetDeviceIDsFromD3D10KHR( - object_, - d3d_device_source, - d3d_object, - d3d_device_set, - n, - ids, - NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_DEVICE_IDS_ERR); - } - - devices->assign(&ids[0], &ids[n]); - return CL_SUCCESS; - } -#endif - - static cl_int get( - VECTOR_CLASS* platforms) - { - cl_uint n = 0; - cl_int err = ::clGetPlatformIDs(0, NULL, &n); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_PLATFORM_IDS_ERR); - } - - cl_platform_id* ids = (cl_platform_id*) alloca( - n * sizeof(cl_platform_id)); - err = ::clGetPlatformIDs(n, ids, NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_PLATFORM_IDS_ERR); - } - - platforms->assign(&ids[0], &ids[n]); - return CL_SUCCESS; - } -}; - -static inline cl_int -UnloadCompiler() -{ - return ::clUnloadCompiler(); -} - -class Context : public detail::Wrapper -{ -public: - Context( - const VECTOR_CLASS& devices, - cl_context_properties* properties = NULL, - void (CL_CALLBACK * notifyFptr)( - const char *, - const void *, - ::size_t, - void *) = NULL, - void* data = NULL, - cl_int* err = NULL) - { - cl_int error; - object_ = ::clCreateContext( - properties, (cl_uint) devices.size(), - (cl_device_id*) &devices.front(), - notifyFptr, data, &error); - - detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR); - if (err != NULL) { - *err = error; - } - } - - Context( - cl_device_type type, - cl_context_properties* properties = NULL, - void (CL_CALLBACK * notifyFptr)( - const char *, - const void *, - ::size_t, - void *) = NULL, - void* data = NULL, - cl_int* err = NULL) - { - cl_int error; - object_ = ::clCreateContextFromType( - properties, type, notifyFptr, data, &error); - - detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR); - if (err != NULL) { - *err = error; - } - } - - Context() : detail::Wrapper() { } - - Context(const Context& context) : detail::Wrapper(context) { } - - Context& operator = (const Context& rhs) - { - if (this != &rhs) { - detail::Wrapper::operator=(rhs); - } - return *this; - } - - template - cl_int getInfo(cl_context_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetContextInfo, object_, name, param), - __GET_CONTEXT_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_context_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - cl_int getSupportedImageFormats( - cl_mem_flags flags, - cl_mem_object_type type, - VECTOR_CLASS* formats) const - { - cl_uint numEntries; - cl_int err = ::clGetSupportedImageFormats( - object_, - flags, - type, - 0, - NULL, - &numEntries); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR); - } - - ImageFormat* value = (ImageFormat*) - alloca(numEntries * sizeof(ImageFormat)); - err = ::clGetSupportedImageFormats( - object_, - flags, - type, - numEntries, - (cl_image_format*) value, - NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR); - } - - formats->assign(&value[0], &value[numEntries]); - return CL_SUCCESS; - } -}; - -__GET_INFO_HELPER_WITH_RETAIN(cl::Context) - -/*! \class Event - * \brief Event interface for cl_event. - */ -class Event : public detail::Wrapper -{ -public: - Event() : detail::Wrapper() { } - - Event(const Event& event) : detail::Wrapper(event) { } - - Event& operator = (const Event& rhs) - { - if (this != &rhs) { - detail::Wrapper::operator=(rhs); - } - return *this; - } - - template - cl_int getInfo(cl_event_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetEventInfo, object_, name, param), - __GET_EVENT_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_event_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - template - cl_int getProfilingInfo(cl_profiling_info name, T* param) const - { - return detail::errHandler(detail::getInfo( - &::clGetEventProfilingInfo, object_, name, param), - __GET_EVENT_PROFILE_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getProfilingInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_profiling_info, name>::param_type param; - cl_int result = getProfilingInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - cl_int wait() const - { - return detail::errHandler( - ::clWaitForEvents(1, &object_), - __WAIT_FOR_EVENTS_ERR); - } - -#if defined(CL_VERSION_1_1) - cl_int setCallback( - cl_int type, - void (CL_CALLBACK * pfn_notify)(cl_event, cl_int, void *), - void * user_data = NULL) - { - return detail::errHandler( - ::clSetEventCallback( - object_, - type, - pfn_notify, - user_data), - __SET_EVENT_CALLBACK_ERR); - } -#endif - - static cl_int - waitForEvents(const VECTOR_CLASS& events) - { - return detail::errHandler( - ::clWaitForEvents( - (cl_uint) events.size(), (cl_event*)&events.front()), - __WAIT_FOR_EVENTS_ERR); - } -}; - -__GET_INFO_HELPER_WITH_RETAIN(cl::Event) - -#if defined(CL_VERSION_1_1) -/*! \class UserEvent - * \brief User event interface for cl_event. - */ -class UserEvent : public Event -{ -public: - UserEvent( - const Context& context, - cl_int * err = NULL) - { - cl_int error; - object_ = ::clCreateUserEvent( - context(), - &error); - - detail::errHandler(error, __CREATE_USER_EVENT_ERR); - if (err != NULL) { - *err = error; - } - } - - UserEvent() : Event() { } - - UserEvent(const UserEvent& event) : Event(event) { } - - UserEvent& operator = (const UserEvent& rhs) - { - if (this != &rhs) { - Event::operator=(rhs); - } - return *this; - } - - cl_int setStatus(cl_int status) - { - return detail::errHandler( - ::clSetUserEventStatus(object_,status), - __SET_USER_EVENT_STATUS_ERR); - } -}; -#endif - -inline static cl_int -WaitForEvents(const VECTOR_CLASS& events) -{ - return detail::errHandler( - ::clWaitForEvents( - (cl_uint) events.size(), (cl_event*)&events.front()), - __WAIT_FOR_EVENTS_ERR); -} - -/*! \class Memory - * \brief Memory interface for cl_mem. - */ -class Memory : public detail::Wrapper -{ -public: - Memory() : detail::Wrapper() { } - - Memory(const Memory& memory) : detail::Wrapper(memory) { } - - Memory& operator = (const Memory& rhs) - { - if (this != &rhs) { - detail::Wrapper::operator=(rhs); - } - return *this; - } - - template - cl_int getInfo(cl_mem_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetMemObjectInfo, object_, name, param), - __GET_MEM_OBJECT_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_mem_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - -#if defined(CL_VERSION_1_1) - cl_int setDestructorCallback( - void (CL_CALLBACK * pfn_notify)(cl_mem, void *), - void * user_data = NULL) - { - return detail::errHandler( - ::clSetMemObjectDestructorCallback( - object_, - pfn_notify, - user_data), - __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR); - } -#endif - -}; - -__GET_INFO_HELPER_WITH_RETAIN(cl::Memory) - -/*! \class Buffer - * \brief Memory buffer interface. - */ -class Buffer : public Memory -{ -public: - Buffer( - const Context& context, - cl_mem_flags flags, - ::size_t size, - void* host_ptr = NULL, - cl_int* err = NULL) - { - cl_int error; - object_ = ::clCreateBuffer(context(), flags, size, host_ptr, &error); - - detail::errHandler(error, __CREATE_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } - - Buffer() : Memory() { } - - Buffer(const Buffer& buffer) : Memory(buffer) { } - - Buffer& operator = (const Buffer& rhs) - { - if (this != &rhs) { - Memory::operator=(rhs); - } - return *this; - } - -#if defined(CL_VERSION_1_1) - Buffer createSubBuffer( - cl_mem_flags flags, - cl_buffer_create_type buffer_create_type, - const void * buffer_create_info, - cl_int * err = NULL) - { - Buffer result; - cl_int error; - result.object_ = ::clCreateSubBuffer( - object_, - flags, - buffer_create_type, - buffer_create_info, - &error); - - detail::errHandler(error, __CREATE_SUBBUFFER_ERR); - if (err != NULL) { - *err = error; - } - - return result; - } -#endif -}; - -#if defined (USE_DX_INTEROP) -class BufferD3D10 : public Buffer -{ -public: - typedef CL_API_ENTRY cl_mem (CL_API_CALL *PFN_clCreateFromD3D10BufferKHR)( - cl_context context, cl_mem_flags flags, ID3D10Buffer* buffer, - cl_int* errcode_ret); - - BufferD3D10( - const Context& context, - cl_mem_flags flags, - ID3D10Buffer* bufobj, - cl_int * err = NULL) - { - static PFN_clCreateFromD3D10BufferKHR pfn_clCreateFromD3D10BufferKHR = NULL; - __INIT_CL_EXT_FCN_PTR(clCreateFromD3D10BufferKHR); - - cl_int error; - object_ = pfn_clCreateFromD3D10BufferKHR( - context(), - flags, - bufobj, - &error); - - detail::errHandler(error, __CREATE_GL_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } - - BufferD3D10() : Buffer() { } - - BufferD3D10(const BufferD3D10& buffer) : Buffer(buffer) { } - - BufferD3D10& operator = (const BufferD3D10& rhs) - { - if (this != &rhs) { - Buffer::operator=(rhs); - } - return *this; - } -}; -#endif - -/*! \class BufferGL - * \brief Memory buffer interface for GL interop. - */ -class BufferGL : public Buffer -{ -public: - BufferGL( - const Context& context, - cl_mem_flags flags, - GLuint bufobj, - cl_int * err = NULL) - { - cl_int error; - object_ = ::clCreateFromGLBuffer( - context(), - flags, - bufobj, - &error); - - detail::errHandler(error, __CREATE_GL_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } - - BufferGL() : Buffer() { } - - BufferGL(const BufferGL& buffer) : Buffer(buffer) { } - - BufferGL& operator = (const BufferGL& rhs) - { - if (this != &rhs) { - Buffer::operator=(rhs); - } - return *this; - } - - cl_int getObjectInfo( - cl_gl_object_type *type, - GLuint * gl_object_name) - { - return detail::errHandler( - ::clGetGLObjectInfo(object_,type,gl_object_name), - __GET_GL_OBJECT_INFO_ERR); - } -}; - -/*! \class BufferRenderGL - * \brief Memory buffer interface for GL interop with renderbuffer. - */ -class BufferRenderGL : public Buffer -{ -public: - BufferRenderGL( - const Context& context, - cl_mem_flags flags, - GLuint bufobj, - cl_int * err = NULL) - { - cl_int error; - object_ = ::clCreateFromGLRenderbuffer( - context(), - flags, - bufobj, - &error); - - detail::errHandler(error, __CREATE_GL_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } - - BufferRenderGL() : Buffer() { } - - BufferRenderGL(const BufferGL& buffer) : Buffer(buffer) { } - - BufferRenderGL& operator = (const BufferRenderGL& rhs) - { - if (this != &rhs) { - Buffer::operator=(rhs); - } - return *this; - } - - cl_int getObjectInfo( - cl_gl_object_type *type, - GLuint * gl_object_name) - { - return detail::errHandler( - ::clGetGLObjectInfo(object_,type,gl_object_name), - __GET_GL_OBJECT_INFO_ERR); - } -}; - -/*! \class Image - * \brief Base class interface for all images. - */ -class Image : public Memory -{ -protected: - Image() : Memory() { } - - Image(const Image& image) : Memory(image) { } - - Image& operator = (const Image& rhs) - { - if (this != &rhs) { - Memory::operator=(rhs); - } - return *this; - } -public: - template - cl_int getImageInfo(cl_image_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetImageInfo, object_, name, param), - __GET_IMAGE_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getImageInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_image_info, name>::param_type param; - cl_int result = getImageInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } -}; - -/*! \class Image2D - * \brief Image interface for 2D images. - */ -class Image2D : public Image -{ -public: - Image2D( - const Context& context, - cl_mem_flags flags, - ImageFormat format, - ::size_t width, - ::size_t height, - ::size_t row_pitch = 0, - void* host_ptr = NULL, - cl_int* err = NULL) - { - cl_int error; - object_ = ::clCreateImage2D( - context(), flags,&format, width, height, row_pitch, host_ptr, &error); - - detail::errHandler(error, __CREATE_IMAGE2D_ERR); - if (err != NULL) { - *err = error; - } - } - - Image2D() { } - - Image2D(const Image2D& image2D) : Image(image2D) { } - - Image2D& operator = (const Image2D& rhs) - { - if (this != &rhs) { - Image::operator=(rhs); - } - return *this; - } -}; - -/*! \class Image2DGL - * \brief 2D image interface for GL interop. - */ -class Image2DGL : public Image2D -{ -public: - Image2DGL( - const Context& context, - cl_mem_flags flags, - GLenum target, - GLint miplevel, - GLuint texobj, - cl_int * err = NULL) - { - cl_int error; - object_ = ::clCreateFromGLTexture2D( - context(), - flags, - target, - miplevel, - texobj, - &error); - - detail::errHandler(error, __CREATE_GL_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } - - Image2DGL() : Image2D() { } - - Image2DGL(const Image2DGL& image) : Image2D(image) { } - - Image2DGL& operator = (const Image2DGL& rhs) - { - if (this != &rhs) { - Image2D::operator=(rhs); - } - return *this; - } -}; - -/*! \class Image3D - * \brief Image interface for 3D images. - */ -class Image3D : public Image -{ -public: - Image3D( - const Context& context, - cl_mem_flags flags, - ImageFormat format, - ::size_t width, - ::size_t height, - ::size_t depth, - ::size_t row_pitch = 0, - ::size_t slice_pitch = 0, - void* host_ptr = NULL, - cl_int* err = NULL) - { - cl_int error; - object_ = ::clCreateImage3D( - context(), flags, &format, width, height, depth, row_pitch, - slice_pitch, host_ptr, &error); - - detail::errHandler(error, __CREATE_IMAGE3D_ERR); - if (err != NULL) { - *err = error; - } - } - - Image3D() { } - - Image3D(const Image3D& image3D) : Image(image3D) { } - - Image3D& operator = (const Image3D& rhs) - { - if (this != &rhs) { - Image::operator=(rhs); - } - return *this; - } -}; - -/*! \class Image2DGL - * \brief 2D image interface for GL interop. - */ -class Image3DGL : public Image3D -{ -public: - Image3DGL( - const Context& context, - cl_mem_flags flags, - GLenum target, - GLint miplevel, - GLuint texobj, - cl_int * err = NULL) - { - cl_int error; - object_ = ::clCreateFromGLTexture3D( - context(), - flags, - target, - miplevel, - texobj, - &error); - - detail::errHandler(error, __CREATE_GL_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - } - - Image3DGL() : Image3D() { } - - Image3DGL(const Image3DGL& image) : Image3D(image) { } - - Image3DGL& operator = (const Image3DGL& rhs) - { - if (this != &rhs) { - Image3D::operator=(rhs); - } - return *this; - } -}; - -/*! \class Sampler - * \brief Sampler interface for cl_sampler. - */ -class Sampler : public detail::Wrapper -{ -public: - Sampler() { } - - Sampler( - const Context& context, - cl_bool normalized_coords, - cl_addressing_mode addressing_mode, - cl_filter_mode filter_mode, - cl_int* err = NULL) - { - cl_int error; - object_ = ::clCreateSampler( - context(), - normalized_coords, - addressing_mode, - filter_mode, - &error); - - detail::errHandler(error, __CREATE_SAMPLER_ERR); - if (err != NULL) { - *err = error; - } - } - - Sampler(const Sampler& sampler) : detail::Wrapper(sampler) { } - - Sampler& operator = (const Sampler& rhs) - { - if (this != &rhs) { - detail::Wrapper::operator=(rhs); - } - return *this; - } - - template - cl_int getInfo(cl_sampler_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetSamplerInfo, object_, name, param), - __GET_SAMPLER_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_sampler_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } -}; - -__GET_INFO_HELPER_WITH_RETAIN(cl::Sampler) - -class Program; -class CommandQueue; -class Kernel; - -/*! \class NDRange - * \brief NDRange interface - */ -class NDRange -{ -private: - size_t<3> sizes_; - cl_uint dimensions_; - -public: - NDRange() - : dimensions_(0) - { } - - NDRange(::size_t size0) - : dimensions_(1) - { - sizes_.push_back(size0); - } - - NDRange(::size_t size0, ::size_t size1) - : dimensions_(2) - { - sizes_.push_back(size0); - sizes_.push_back(size1); - } - - NDRange(::size_t size0, ::size_t size1, ::size_t size2) - : dimensions_(3) - { - sizes_.push_back(size0); - sizes_.push_back(size1); - sizes_.push_back(size2); - } - - operator const ::size_t*() const { return (const ::size_t*) sizes_; } - ::size_t dimensions() const { return dimensions_; } -}; - -static const NDRange NullRange; - -/*! - * \struct LocalSpaceArg - * \brief Local address raper for use with Kernel::setArg - */ -struct LocalSpaceArg -{ - ::size_t size_; -}; - -namespace detail { - -template -struct KernelArgumentHandler -{ - static ::size_t size(const T&) { return sizeof(T); } - static T* ptr(T& value) { return &value; } -}; - -template <> -struct KernelArgumentHandler -{ - static ::size_t size(const LocalSpaceArg& value) { return value.size_; } - static void* ptr(LocalSpaceArg&) { return NULL; } -}; - -} -//! \endcond - -inline LocalSpaceArg -__local(::size_t size) -{ - LocalSpaceArg ret = { size }; - return ret; -} - -class KernelFunctor; - -/*! \class Kernel - * \brief Kernel interface that implements cl_kernel - */ -class Kernel : public detail::Wrapper -{ -public: - inline Kernel(const Program& program, const char* name, cl_int* err = NULL); - - Kernel() { } - - Kernel(const Kernel& kernel) : detail::Wrapper(kernel) { } - - Kernel& operator = (const Kernel& rhs) - { - if (this != &rhs) { - detail::Wrapper::operator=(rhs); - } - return *this; - } - - template - cl_int getInfo(cl_kernel_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetKernelInfo, object_, name, param), - __GET_KERNEL_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_kernel_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - template - cl_int getWorkGroupInfo( - const Device& device, cl_kernel_work_group_info name, T* param) const - { - return detail::errHandler( - detail::getInfo( - &::clGetKernelWorkGroupInfo, object_, device(), name, param), - __GET_KERNEL_WORK_GROUP_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getWorkGroupInfo(const Device& device, cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_kernel_work_group_info, name>::param_type param; - cl_int result = getWorkGroupInfo(device, name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - template - cl_int setArg(cl_uint index, T value) - { - return detail::errHandler( - ::clSetKernelArg( - object_, - index, - detail::KernelArgumentHandler::size(value), - detail::KernelArgumentHandler::ptr(value)), - __SET_KERNEL_ARGS_ERR); - } - - cl_int setArg(cl_uint index, ::size_t size, void* argPtr) - { - return detail::errHandler( - ::clSetKernelArg(object_, index, size, argPtr), - __SET_KERNEL_ARGS_ERR); - } - - KernelFunctor bind( - const CommandQueue& queue, - const NDRange& offset, - const NDRange& global, - const NDRange& local); - - KernelFunctor bind( - const CommandQueue& queue, - const NDRange& global, - const NDRange& local); -}; - -__GET_INFO_HELPER_WITH_RETAIN(cl::Kernel) - -/*! \class Program - * \brief Program interface that implements cl_program. - */ -class Program : public detail::Wrapper -{ -public: - typedef VECTOR_CLASS > Binaries; - typedef VECTOR_CLASS > Sources; - - Program( - const Context& context, - const Sources& sources, - cl_int* err = NULL) - { - cl_int error; - - const ::size_t n = (::size_t)sources.size(); - ::size_t* lengths = (::size_t*) alloca(n * sizeof(::size_t)); - const char** strings = (const char**) alloca(n * sizeof(const char*)); - - for (::size_t i = 0; i < n; ++i) { - strings[i] = sources[(int)i].first; - lengths[i] = sources[(int)i].second; - } - - object_ = ::clCreateProgramWithSource( - context(), (cl_uint)n, strings, lengths, &error); - - detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR); - if (err != NULL) { - *err = error; - } - } - - Program( - const Context& context, - const VECTOR_CLASS& devices, - const Binaries& binaries, - VECTOR_CLASS* binaryStatus = NULL, - cl_int* err = NULL) - { - cl_int error; - const ::size_t n = binaries.size(); - ::size_t* lengths = (::size_t*) alloca(n * sizeof(::size_t)); - const unsigned char** images = (const unsigned char**) alloca(n * sizeof(const void*)); - - for (::size_t i = 0; i < n; ++i) { - images[i] = (const unsigned char*)binaries[(int)i].first; - lengths[i] = binaries[(int)i].second; - } - - object_ = ::clCreateProgramWithBinary( - context(), (cl_uint) devices.size(), - (cl_device_id*)&devices.front(), - lengths, images, binaryStatus != NULL - ? (cl_int*) &binaryStatus->front() - : NULL, &error); - - detail::errHandler(error, __CREATE_PROGRAM_WITH_BINARY_ERR); - if (err != NULL) { - *err = error; - } - } - - Program() { } - - Program(const Program& program) : detail::Wrapper(program) { } - - Program& operator = (const Program& rhs) - { - if (this != &rhs) { - detail::Wrapper::operator=(rhs); - } - return *this; - } - - cl_int build( - const VECTOR_CLASS& devices, - const char* options = NULL, - void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL, - void* data = NULL) const - { - return detail::errHandler( - ::clBuildProgram( - object_, - (cl_uint) - devices.size(), - (cl_device_id*)&devices.front(), - options, - notifyFptr, - data), - __BUILD_PROGRAM_ERR); - } - - template - cl_int getInfo(cl_program_info name, T* param) const - { - return detail::errHandler( - detail::getInfo(&::clGetProgramInfo, object_, name, param), - __GET_PROGRAM_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_program_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - template - cl_int getBuildInfo( - const Device& device, cl_program_build_info name, T* param) const - { - return detail::errHandler( - detail::getInfo( - &::clGetProgramBuildInfo, object_, device(), name, param), - __GET_PROGRAM_BUILD_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getBuildInfo(const Device& device, cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_program_build_info, name>::param_type param; - cl_int result = getBuildInfo(device, name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - cl_int createKernels(VECTOR_CLASS* kernels) - { - cl_uint numKernels; - cl_int err = ::clCreateKernelsInProgram(object_, 0, NULL, &numKernels); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR); - } - - Kernel* value = (Kernel*) alloca(numKernels * sizeof(Kernel)); - err = ::clCreateKernelsInProgram( - object_, numKernels, (cl_kernel*) value, NULL); - if (err != CL_SUCCESS) { - return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR); - } - - kernels->assign(&value[0], &value[numKernels]); - return CL_SUCCESS; - } -}; - -__GET_INFO_HELPER_WITH_RETAIN(cl::Program) - -inline Kernel::Kernel(const Program& program, const char* name, cl_int* err) -{ - cl_int error; - - object_ = ::clCreateKernel(program(), name, &error); - detail::errHandler(error, __CREATE_KERNEL_ERR); - - if (err != NULL) { - *err = error; - } - -} - -/*! \class CommandQueue - * \brief CommandQueue interface for cl_command_queue. - */ -class CommandQueue : public detail::Wrapper -{ -public: - CommandQueue( - const Context& context, - const Device& device, - cl_command_queue_properties properties = 0, - cl_int* err = NULL) - { - cl_int error; - object_ = ::clCreateCommandQueue( - context(), device(), properties, &error); - - detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR); - if (err != NULL) { - *err = error; - } - } - - CommandQueue() { } - - CommandQueue(const CommandQueue& commandQueue) : detail::Wrapper(commandQueue) { } - - CommandQueue& operator = (const CommandQueue& rhs) - { - if (this != &rhs) { - detail::Wrapper::operator=(rhs); - } - return *this; - } - - template - cl_int getInfo(cl_command_queue_info name, T* param) const - { - return detail::errHandler( - detail::getInfo( - &::clGetCommandQueueInfo, object_, name, param), - __GET_COMMAND_QUEUE_INFO_ERR); - } - - template typename - detail::param_traits::param_type - getInfo(cl_int* err = NULL) const - { - typename detail::param_traits< - detail::cl_command_queue_info, name>::param_type param; - cl_int result = getInfo(name, ¶m); - if (err != NULL) { - *err = result; - } - return param; - } - - cl_int enqueueReadBuffer( - const Buffer& buffer, - cl_bool blocking, - ::size_t offset, - ::size_t size, - void* ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueReadBuffer( - object_, buffer(), blocking, offset, size, - ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_READ_BUFFER_ERR); - } - - cl_int enqueueWriteBuffer( - const Buffer& buffer, - cl_bool blocking, - ::size_t offset, - ::size_t size, - const void* ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueWriteBuffer( - object_, buffer(), blocking, offset, size, - ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_WRITE_BUFFER_ERR); - } - - cl_int enqueueCopyBuffer( - const Buffer& src, - const Buffer& dst, - ::size_t src_offset, - ::size_t dst_offset, - ::size_t size, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueCopyBuffer( - object_, src(), dst(), src_offset, dst_offset, size, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQEUE_COPY_BUFFER_ERR); - } - -#if defined(CL_VERSION_1_1) - cl_int enqueueReadBufferRect( - const Buffer& buffer, - cl_bool blocking, - const size_t<3>& buffer_offset, - const size_t<3>& host_offset, - const size_t<3>& region, - ::size_t buffer_row_pitch, - ::size_t buffer_slice_pitch, - ::size_t host_row_pitch, - ::size_t host_slice_pitch, - void *ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueReadBufferRect( - object_, - buffer(), - blocking, - (const ::size_t *)buffer_offset, - (const ::size_t *)host_offset, - (const ::size_t *)region, - buffer_row_pitch, - buffer_slice_pitch, - host_row_pitch, - host_slice_pitch, - ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_READ_BUFFER_RECT_ERR); - } - - - cl_int enqueueWriteBufferRect( - const Buffer& buffer, - cl_bool blocking, - const size_t<3>& buffer_offset, - const size_t<3>& host_offset, - const size_t<3>& region, - ::size_t buffer_row_pitch, - ::size_t buffer_slice_pitch, - ::size_t host_row_pitch, - ::size_t host_slice_pitch, - void *ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueWriteBufferRect( - object_, - buffer(), - blocking, - (const ::size_t *)buffer_offset, - (const ::size_t *)host_offset, - (const ::size_t *)region, - buffer_row_pitch, - buffer_slice_pitch, - host_row_pitch, - host_slice_pitch, - ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_WRITE_BUFFER_RECT_ERR); - } - - cl_int enqueueCopyBufferRect( - const Buffer& src, - const Buffer& dst, - const size_t<3>& src_origin, - const size_t<3>& dst_origin, - const size_t<3>& region, - ::size_t src_row_pitch, - ::size_t src_slice_pitch, - ::size_t dst_row_pitch, - ::size_t dst_slice_pitch, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueCopyBufferRect( - object_, - src(), - dst(), - (const ::size_t *)src_origin, - (const ::size_t *)dst_origin, - (const ::size_t *)region, - src_row_pitch, - src_slice_pitch, - dst_row_pitch, - dst_slice_pitch, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQEUE_COPY_BUFFER_RECT_ERR); - } -#endif - - cl_int enqueueReadImage( - const Image& image, - cl_bool blocking, - const size_t<3>& origin, - const size_t<3>& region, - ::size_t row_pitch, - ::size_t slice_pitch, - void* ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueReadImage( - object_, image(), blocking, (const ::size_t *) origin, - (const ::size_t *) region, row_pitch, slice_pitch, ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_READ_IMAGE_ERR); - } - - cl_int enqueueWriteImage( - const Image& image, - cl_bool blocking, - const size_t<3>& origin, - const size_t<3>& region, - ::size_t row_pitch, - ::size_t slice_pitch, - void* ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueWriteImage( - object_, image(), blocking, (const ::size_t *) origin, - (const ::size_t *) region, row_pitch, slice_pitch, ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_WRITE_IMAGE_ERR); - } - - cl_int enqueueCopyImage( - const Image& src, - const Image& dst, - const size_t<3>& src_origin, - const size_t<3>& dst_origin, - const size_t<3>& region, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueCopyImage( - object_, src(), dst(), (const ::size_t *) src_origin, - (const ::size_t *)dst_origin, (const ::size_t *) region, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_COPY_IMAGE_ERR); - } - - cl_int enqueueCopyImageToBuffer( - const Image& src, - const Buffer& dst, - const size_t<3>& src_origin, - const size_t<3>& region, - ::size_t dst_offset, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueCopyImageToBuffer( - object_, src(), dst(), (const ::size_t *) src_origin, - (const ::size_t *) region, dst_offset, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR); - } - - cl_int enqueueCopyBufferToImage( - const Buffer& src, - const Image& dst, - ::size_t src_offset, - const size_t<3>& dst_origin, - const size_t<3>& region, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueCopyBufferToImage( - object_, src(), dst(), src_offset, - (const ::size_t *) dst_origin, (const ::size_t *) region, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR); - } - - void* enqueueMapBuffer( - const Buffer& buffer, - cl_bool blocking, - cl_map_flags flags, - ::size_t offset, - ::size_t size, - const VECTOR_CLASS* events = NULL, - Event* event = NULL, - cl_int* err = NULL) const - { - cl_int error; - void * result = ::clEnqueueMapBuffer( - object_, buffer(), blocking, flags, offset, size, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event, - &error); - - detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR); - if (err != NULL) { - *err = error; - } - return result; - } - - void* enqueueMapImage( - const Image& buffer, - cl_bool blocking, - cl_map_flags flags, - const size_t<3>& origin, - const size_t<3>& region, - ::size_t * row_pitch, - ::size_t * slice_pitch, - const VECTOR_CLASS* events = NULL, - Event* event = NULL, - cl_int* err = NULL) const - { - cl_int error; - void * result = ::clEnqueueMapImage( - object_, buffer(), blocking, flags, - (const ::size_t *) origin, (const ::size_t *) region, - row_pitch, slice_pitch, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event, - &error); - - detail::errHandler(error, __ENQUEUE_MAP_IMAGE_ERR); - if (err != NULL) { - *err = error; - } - return result; - } - - cl_int enqueueUnmapMemObject( - const Memory& memory, - void* mapped_ptr, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueUnmapMemObject( - object_, memory(), mapped_ptr, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_UNMAP_MEM_OBJECT_ERR); - } - - cl_int enqueueNDRangeKernel( - const Kernel& kernel, - const NDRange& offset, - const NDRange& global, - const NDRange& local, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueNDRangeKernel( - object_, kernel(), (cl_uint) global.dimensions(), - offset.dimensions() != 0 ? (const ::size_t*) offset : NULL, - (const ::size_t*) global, - local.dimensions() != 0 ? (const ::size_t*) local : NULL, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_NDRANGE_KERNEL_ERR); - } - - cl_int enqueueTask( - const Kernel& kernel, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueTask( - object_, kernel(), - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_TASK_ERR); - } - - cl_int enqueueNativeKernel( - void (*userFptr)(void *), - std::pair args, - const VECTOR_CLASS* mem_objects = NULL, - const VECTOR_CLASS* mem_locs = NULL, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - cl_mem * mems = (mem_objects != NULL && mem_objects->size() > 0) - ? (cl_mem*) alloca(mem_objects->size() * sizeof(cl_mem)) - : NULL; - - if (mems != NULL) { - for (unsigned int i = 0; i < mem_objects->size(); i++) { - mems[i] = ((*mem_objects)[i])(); - } - } - - return detail::errHandler( - ::clEnqueueNativeKernel( - object_, userFptr, args.first, args.second, - (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, - mems, - (mem_locs != NULL) ? (const void **) &mem_locs->front() : NULL, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_NATIVE_KERNEL); - } - - cl_int enqueueMarker(Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueMarker(object_, (cl_event*) event), - __ENQUEUE_MARKER_ERR); - } - - cl_int enqueueWaitForEvents(const VECTOR_CLASS& events) const - { - return detail::errHandler( - ::clEnqueueWaitForEvents( - object_, - (cl_uint) events.size(), - (const cl_event*) &events.front()), - __ENQUEUE_WAIT_FOR_EVENTS_ERR); - } - - cl_int enqueueAcquireGLObjects( - const VECTOR_CLASS* mem_objects = NULL, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueAcquireGLObjects( - object_, - (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, - (mem_objects != NULL) ? (const cl_mem *) &mem_objects->front(): NULL, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_ACQUIRE_GL_ERR); - } - - cl_int enqueueReleaseGLObjects( - const VECTOR_CLASS* mem_objects = NULL, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - return detail::errHandler( - ::clEnqueueReleaseGLObjects( - object_, - (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, - (mem_objects != NULL) ? (const cl_mem *) &mem_objects->front(): NULL, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_RELEASE_GL_ERR); - } - -#if defined (USE_DX_INTEROP) -typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueAcquireD3D10ObjectsKHR)( - cl_command_queue command_queue, cl_uint num_objects, - const cl_mem* mem_objects, cl_uint num_events_in_wait_list, - const cl_event* event_wait_list, cl_event* event); -typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueReleaseD3D10ObjectsKHR)( - cl_command_queue command_queue, cl_uint num_objects, - const cl_mem* mem_objects, cl_uint num_events_in_wait_list, - const cl_event* event_wait_list, cl_event* event); - - cl_int enqueueAcquireD3D10Objects( - const VECTOR_CLASS* mem_objects = NULL, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - static PFN_clEnqueueAcquireD3D10ObjectsKHR pfn_clEnqueueAcquireD3D10ObjectsKHR = NULL; - __INIT_CL_EXT_FCN_PTR(clEnqueueAcquireD3D10ObjectsKHR); - - return detail::errHandler( - pfn_clEnqueueAcquireD3D10ObjectsKHR( - object_, - (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, - (mem_objects != NULL) ? (const cl_mem *) &mem_objects->front(): NULL, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_ACQUIRE_GL_ERR); - } - - cl_int enqueueReleaseD3D10Objects( - const VECTOR_CLASS* mem_objects = NULL, - const VECTOR_CLASS* events = NULL, - Event* event = NULL) const - { - static PFN_clEnqueueReleaseD3D10ObjectsKHR pfn_clEnqueueReleaseD3D10ObjectsKHR = NULL; - __INIT_CL_EXT_FCN_PTR(clEnqueueReleaseD3D10ObjectsKHR); - - return detail::errHandler( - pfn_clEnqueueReleaseD3D10ObjectsKHR( - object_, - (mem_objects != NULL) ? (cl_uint) mem_objects->size() : 0, - (mem_objects != NULL) ? (const cl_mem *) &mem_objects->front(): NULL, - (events != NULL) ? (cl_uint) events->size() : 0, - (events != NULL) ? (cl_event*) &events->front() : NULL, - (cl_event*) event), - __ENQUEUE_RELEASE_GL_ERR); - } -#endif - - cl_int enqueueBarrier() const - { - return detail::errHandler( - ::clEnqueueBarrier(object_), - __ENQUEUE_BARRIER_ERR); - } - - cl_int flush() const - { - return detail::errHandler(::clFlush(object_), __FLUSH_ERR); - } - - cl_int finish() const - { - return detail::errHandler(::clFinish(object_), __FINISH_ERR); - } -}; - -__GET_INFO_HELPER_WITH_RETAIN(cl::CommandQueue) - -/*! \class KernelFunctor - * \brief Kernel functor interface - * - * \note Currently only functors of zero to ten arguments are supported. It - * is straightforward to add more and a more general solution, similar to - * Boost.Lambda could be followed if required in the future. - */ -class KernelFunctor -{ -private: - Kernel kernel_; - CommandQueue queue_; - NDRange offset_; - NDRange global_; - NDRange local_; - - cl_int err_; -public: - KernelFunctor() { } - - KernelFunctor( - const Kernel& kernel, - const CommandQueue& queue, - const NDRange& offset, - const NDRange& global, - const NDRange& local) : - kernel_(kernel), - queue_(queue), - offset_(offset), - global_(global), - local_(local), - err_(CL_SUCCESS) - {} - - KernelFunctor& operator=(const KernelFunctor& rhs); - - KernelFunctor(const KernelFunctor& rhs); - - cl_int getError() { return err_; } - - inline Event operator()(const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const A12& a12, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const A12& a12, - const A13& a13, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const A12& a12, - const A13& a13, - const A14& a14, - const VECTOR_CLASS* events = NULL); - - template - inline Event operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const A12& a12, - const A13& a13, - const A14& a14, - const A15& a15, - const VECTOR_CLASS* events = NULL); -}; - -inline KernelFunctor Kernel::bind( - const CommandQueue& queue, - const NDRange& offset, - const NDRange& global, - const NDRange& local) -{ - return KernelFunctor(*this,queue,offset,global,local); -} - -inline KernelFunctor Kernel::bind( - const CommandQueue& queue, - const NDRange& global, - const NDRange& local) -{ - return KernelFunctor(*this,queue,NullRange,global,local); -} - -inline KernelFunctor& KernelFunctor::operator=(const KernelFunctor& rhs) -{ - if (this == &rhs) { - return *this; - } - - kernel_ = rhs.kernel_; - queue_ = rhs.queue_; - offset_ = rhs.offset_; - global_ = rhs.global_; - local_ = rhs.local_; - - return *this; -} - -inline KernelFunctor::KernelFunctor(const KernelFunctor& rhs) : - kernel_(rhs.kernel_), - queue_(rhs.queue_), - offset_(rhs.offset_), - global_(rhs.global_), - local_(rhs.local_) -{ -} - -Event KernelFunctor::operator()(const VECTOR_CLASS* events) -{ - Event event; - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - kernel_.setArg(6,a7); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - kernel_.setArg(6,a7); - kernel_.setArg(7,a8); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - kernel_.setArg(6,a7); - kernel_.setArg(7,a8); - kernel_.setArg(8,a9); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - kernel_.setArg(6,a7); - kernel_.setArg(7,a8); - kernel_.setArg(8,a9); - kernel_.setArg(9,a10); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - kernel_.setArg(6,a7); - kernel_.setArg(7,a8); - kernel_.setArg(8,a9); - kernel_.setArg(9,a10); - kernel_.setArg(10,a11); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const A12& a12, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - kernel_.setArg(6,a7); - kernel_.setArg(7,a8); - kernel_.setArg(8,a9); - kernel_.setArg(9,a10); - kernel_.setArg(10,a11); - kernel_.setArg(11,a12); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const A12& a12, - const A13& a13, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - kernel_.setArg(6,a7); - kernel_.setArg(7,a8); - kernel_.setArg(8,a9); - kernel_.setArg(9,a10); - kernel_.setArg(10,a11); - kernel_.setArg(11,a12); - kernel_.setArg(12,a13); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const A12& a12, - const A13& a13, - const A14& a14, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - kernel_.setArg(6,a7); - kernel_.setArg(7,a8); - kernel_.setArg(8,a9); - kernel_.setArg(9,a10); - kernel_.setArg(10,a11); - kernel_.setArg(11,a12); - kernel_.setArg(12,a13); - kernel_.setArg(13,a14); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -template -Event KernelFunctor::operator()( - const A1& a1, - const A2& a2, - const A3& a3, - const A4& a4, - const A5& a5, - const A6& a6, - const A7& a7, - const A8& a8, - const A9& a9, - const A10& a10, - const A11& a11, - const A12& a12, - const A13& a13, - const A14& a14, - const A15& a15, - const VECTOR_CLASS* events) -{ - Event event; - - kernel_.setArg(0,a1); - kernel_.setArg(1,a2); - kernel_.setArg(2,a3); - kernel_.setArg(3,a4); - kernel_.setArg(4,a5); - kernel_.setArg(5,a6); - kernel_.setArg(6,a7); - kernel_.setArg(7,a8); - kernel_.setArg(8,a9); - kernel_.setArg(9,a10); - kernel_.setArg(10,a11); - kernel_.setArg(11,a12); - kernel_.setArg(12,a13); - kernel_.setArg(13,a14); - kernel_.setArg(14,a15); - - err_ = queue_.enqueueNDRangeKernel( - kernel_, - offset_, - global_, - local_, - NULL, // bgaster_fixme - do we want to allow wait event lists? - &event); - - return event; -} - -#undef __ERR_STR -#if !defined(__CL_USER_OVERRIDE_ERROR_STRINGS) -#undef __GET_DEVICE_INFO_ERR -#undef __GET_PLATFORM_INFO_ERR -#undef __GET_DEVICE_IDS_ERR -#undef __GET_CONTEXT_INFO_ERR -#undef __GET_EVENT_INFO_ERR -#undef __GET_EVENT_PROFILE_INFO_ERR -#undef __GET_MEM_OBJECT_INFO_ERR -#undef __GET_IMAGE_INFO_ERR -#undef __GET_SAMPLER_INFO_ERR -#undef __GET_KERNEL_INFO_ERR -#undef __GET_KERNEL_WORK_GROUP_INFO_ERR -#undef __GET_PROGRAM_INFO_ERR -#undef __GET_PROGRAM_BUILD_INFO_ERR -#undef __GET_COMMAND_QUEUE_INFO_ERR - -#undef __CREATE_CONTEXT_FROM_TYPE_ERR -#undef __GET_SUPPORTED_IMAGE_FORMATS_ERR - -#undef __CREATE_BUFFER_ERR -#undef __CREATE_SUBBUFFER_ERR -#undef __CREATE_IMAGE2D_ERR -#undef __CREATE_IMAGE3D_ERR -#undef __CREATE_SAMPLER_ERR -#undef __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR - -#undef __CREATE_USER_EVENT_ERR -#undef __SET_USER_EVENT_STATUS_ERR -#undef __SET_EVENT_CALLBACK_ERR - -#undef __WAIT_FOR_EVENTS_ERR - -#undef __CREATE_KERNEL_ERR -#undef __SET_KERNEL_ARGS_ERR -#undef __CREATE_PROGRAM_WITH_SOURCE_ERR -#undef __CREATE_PROGRAM_WITH_BINARY_ERR -#undef __BUILD_PROGRAM_ERR -#undef __CREATE_KERNELS_IN_PROGRAM_ERR - -#undef __CREATE_COMMAND_QUEUE_ERR -#undef __SET_COMMAND_QUEUE_PROPERTY_ERR -#undef __ENQUEUE_READ_BUFFER_ERR -#undef __ENQUEUE_WRITE_BUFFER_ERR -#undef __ENQUEUE_READ_BUFFER_RECT_ERR -#undef __ENQUEUE_WRITE_BUFFER_RECT_ERR -#undef __ENQEUE_COPY_BUFFER_ERR -#undef __ENQEUE_COPY_BUFFER_RECT_ERR -#undef __ENQUEUE_READ_IMAGE_ERR -#undef __ENQUEUE_WRITE_IMAGE_ERR -#undef __ENQUEUE_COPY_IMAGE_ERR -#undef __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR -#undef __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR -#undef __ENQUEUE_MAP_BUFFER_ERR -#undef __ENQUEUE_MAP_IMAGE_ERR -#undef __ENQUEUE_UNMAP_MEM_OBJECT_ERR -#undef __ENQUEUE_NDRANGE_KERNEL_ERR -#undef __ENQUEUE_TASK_ERR -#undef __ENQUEUE_NATIVE_KERNEL - -#undef __UNLOAD_COMPILER_ERR -#endif //__CL_USER_OVERRIDE_ERROR_STRINGS - -#undef __GET_INFO_HELPER_WITH_RETAIN - -// Extensions -#undef __INIT_CL_EXT_FCN_PTR -#undef __CREATE_SUB_DEVICES - -#if defined(USE_CL_DEVICE_FISSION) -#undef __PARAM_NAME_DEVICE_FISSION -#endif // USE_CL_DEVICE_FISSION - -} // namespace cl - -#endif // CL_HPP_ diff --git a/KGeoBag/CMakeLists.txt b/KGeoBag/CMakeLists.txt index 32da29cb5..f78b2e998 100644 --- a/KGeoBag/CMakeLists.txt +++ b/KGeoBag/CMakeLists.txt @@ -2,8 +2,8 @@ cmake_minimum_required( VERSION ${CMAKE_MINIMUM_VERSION} ) # KGeoBag version set( MODULE_VERSION_MAJOR 3 ) -set( MODULE_VERSION_MINOR 7 ) -set( MODULE_VERSION_PATCH 7 ) +set( MODULE_VERSION_MINOR 8 ) +set( MODULE_VERSION_PATCH 0 ) set( MODULE_VERSION "${MODULE_VERSION_MAJOR}.${MODULE_VERSION_MINOR}.${MODULE_VERSION_PATCH}" ) #project( KGeoBag VERSION ${MODULE_VERSION}) @@ -11,43 +11,27 @@ project( KGeoBag ) include( KasperDefaults ) - -# internal dependencies -kasper_find_module( Kommon ) -foreach( FLAG ${Kommon_CFLAGS} ) - add_definitions( -D${FLAG} ) -endforeach( FLAG ) - -# external dependencies -find_package( GSL REQUIRED ) -kasper_external_include_directories( ${GSL_INCLUDE_DIRS} ) - #option( KGeoBag_USE_VTK "Enable visualization with VTK" OFF ) #option( KGeoBag_USE_ROOT "Enable visualization with ROOT" OFF ) set( KGeoBag_USE_BOOST ${KASPER_USE_BOOST} ) set( KGeoBag_USE_VTK ${KASPER_USE_VTK} ) set( KGeoBag_USE_ROOT ${KASPER_USE_ROOT} ) +set( KGeoBag_USE_GSL ${KASPER_USE_GSL} ) + +if( KGeoBag_USE_GSL ) + find_package( GSL REQUIRED ) +endif( KGeoBag_USE_GSL ) if( KGeoBag_USE_BOOST ) - find_package( Boost 1.43.0 COMPONENTS filesystem REQUIRED ) - if( Boost_INCLUDE_DIR ) - kasper_external_include_directories( ${Boost_INCLUDE_DIR} ) - list(APPEND EXTERNAL_LIBRARIES ${Boost_LIBRARIES} ) - else() - list(APPEND EXTERNAL_LIBRARIES Boost::headers Boost::filesystem ) - endif() - set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS KGeoBag_USE_BOOST ) + find_package( Boost ${BOOST_MINIMUM_VERSION} REQUIRED ) endif() if( KGeoBag_USE_VTK ) - kasper_find_vtk() - set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS KGeoBag_USE_VTK ) + find_package(VTK CONFIG REQUIRED) endif() if( KGeoBag_USE_ROOT ) - find_package( ROOT REQUIRED ) - kasper_external_include_directories( ${ROOT_INCLUDE_DIRS} ) - set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS KGeoBag_USE_ROOT ) + find_package( ROOT ${ROOT_MINIMUM_VERSION} CONFIG REQUIRED ) endif() # installing @@ -55,9 +39,6 @@ kasper_module_paths( TheBag ) # debugging kasper_module_debug() -if( KGeoBag_ENABLE_DEBUG ) - add_cflag (KGeoBag_ENABLE_DEBUG) -endif() ## testing kasper_module_test( Source/Test ) diff --git a/KGeoBag/KGeoBagConfig.cmake.in b/KGeoBag/KGeoBagConfig.cmake.in new file mode 100644 index 000000000..a38002d3c --- /dev/null +++ b/KGeoBag/KGeoBagConfig.cmake.in @@ -0,0 +1,28 @@ +include(CMakeFindDependencyMacro) + +set(KGeoBag_USE_GSL @KGeoBag_USE_GSL@) +if(KGeoBag_USE_GSL) + find_dependency( GSL ) +endif(KGeoBag_USE_GSL) + +set(KGeoBag_USE_BOOST @KGeoBag_USE_BOOST@) +if(KGeoBag_USE_BOOST) + find_dependency( Boost COMPONENTS ) +endif(KGeoBag_USE_BOOST) + +set(KGeoBag_USE_VTK @KGeoBag_USE_VTK@) +if(KGeoBag_USE_VTK) + find_dependency( VTK NO_MODULE ) +endif(KGeoBag_USE_VTK) + +set(KGeoBag_USE_ROOT @KGeoBag_USE_ROOT@) +if(KGeoBag_USE_ROOT) + find_dependency( ROOT CONFIG ) +endif(KGeoBag_USE_ROOT) + +# Kasper dependencies +find_dependency( Kommon ) + +if(NOT TARGET @PROJECT_NAME@::@PROJECT_NAME@) + include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +endif() diff --git a/Kassiopeia/ModuleConfigVersion.cmake.in b/KGeoBag/KGeoBagConfigVersion.cmake.in similarity index 83% rename from Kassiopeia/ModuleConfigVersion.cmake.in rename to KGeoBag/KGeoBagConfigVersion.cmake.in index 1392f662f..25f052f29 100644 --- a/Kassiopeia/ModuleConfigVersion.cmake.in +++ b/KGeoBag/KGeoBagConfigVersion.cmake.in @@ -1,7 +1,5 @@ -# $Id: ModuleConfigVersion.cmake.in 11916 2012-01-20 18:16:45Z s_voec01 $ - set(PACKAGE_VERSION "@MODULE_VERSION@") - + # Check whether the requested PACKAGE_FIND_VERSION is compatible if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") set(PACKAGE_VERSION_COMPATIBLE FALSE) diff --git a/KGeoBag/ModuleConfig.cmake.in b/KGeoBag/ModuleConfig.cmake.in deleted file mode 100644 index e418a7eb3..000000000 --- a/KGeoBag/ModuleConfig.cmake.in +++ /dev/null @@ -1,26 +0,0 @@ -# $Id: ModuleConfig.cmake.in 12255 2012-03-16 09:26:20Z s_voec01 $ - -if(@PROJECT_NAME@_FOUND) - return() -endif() - -set(@PROJECT_NAME@_FOUND TRUE) - -# Update this section -# The extra libraries one has to link against -set(@PROJECT_NAME@_DEPENDS @Kommon_LIBRARIES@ @Kommon_Vtk_LIBRARIES@ @ROOT_LIBRARIES@ @VTK_LIBRARIES@) -list(REMOVE_DUPLICATES @PROJECT_NAME@_DEPENDS) -# End - -set(@PROJECT_NAME@_VERSION_MAJOR @MODULE_VERSION_MAJOR@) -set(@PROJECT_NAME@_VERSION_MINOR @MODULE_VERSION_MINOR@) -set(@PROJECT_NAME@_VERSION_PATCH @MODULE_VERSION_PATCH@) -set(@PROJECT_NAME@_VERSION @MODULE_VERSION@) - -set(@PROJECT_NAME@_CFLAGS @MODULE_CFLAGS@) -set(@PROJECT_NAME@_INCLUDE_DIRS @MODULE_INCLUDE_DIRS@) -set(@PROJECT_NAME@_LIBRARIES @MODULE_TARGETS@ ) -foreach(LIB @MODULE_TARGETS@) -set(@PROJECT_NAME@_LIBRARIES_MPI "${@PROJECT_NAME@_LIBRARIES_MPI} ${LIB}_mpi") -endforeach(LIB) -mark_as_advanced(@PROJECT_NAME@_DIR) diff --git a/KGeoBag/ModuleConfigInstalled.cmake.in b/KGeoBag/ModuleConfigInstalled.cmake.in deleted file mode 100644 index 17d7add0e..000000000 --- a/KGeoBag/ModuleConfigInstalled.cmake.in +++ /dev/null @@ -1,33 +0,0 @@ -# $Id: ModuleConfig.cmake.in 11925 2012-01-23 14:54:05Z s_voec01 $ - -if(@PROJECT_NAME@_FOUND) - return() -endif() - -set(@PROJECT_NAME@_FOUND TRUE) - -# Update this section -set(@PROJECT_NAME@_DEPENDS @Kommon_LIBRARIES@ @Kommon_Vtk_LIBRARIES@ @ROOT_LIBRARIES@ @VTK_LIBRARIES@) -list(REMOVE_DUPLICATES @PROJECT_NAME@_DEPENDS) -# End - -set(@PROJECT_NAME@_VERSION_MAJOR @MODULE_VERSION_MAJOR@) -set(@PROJECT_NAME@_VERSION_MINOR @MODULE_VERSION_MINOR@) -set(@PROJECT_NAME@_VERSION_PATCH @MODULE_VERSION_PATCH@) -set(@PROJECT_NAME@_VERSION @MODULE_VERSION@) - -get_filename_component(MODULE_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) -if(EXISTS "${MODULE_CMAKE_DIR}/ModuleTargets.cmake") - include("${MODULE_CMAKE_DIR}/ModuleTargets.cmake") -elseif(NOT KASPER_TARGETS_INCLUDED) - include("${MODULE_CMAKE_DIR}/../Kasper/KasperTargets.cmake") - set(KASPER_TARGETS_INCLUDED TRUE) -endif() - -set(@PROJECT_NAME@_CFLAGS @MODULE_CFLAGS@) -set(@PROJECT_NAME@_INCLUDE_DIRS @INSTALLED_INCLUDE_DIRS@) -set(@PROJECT_NAME@_LIBRARIES @MODULE_TARGETS@ ) -set(@PROJECT_NAME@_MPI_LIBRARIES "-L@CMAKE_INSTALL_PREFIX@/lib") -foreach(LIB @MODULE_TARGETS@) -set(@PROJECT_NAME@_MPI_LIBRARIES "${@PROJECT_NAME@_MPI_LIBRARIES} -l${LIB}_mpi") -endforeach(LIB) diff --git a/KGeoBag/ModuleConfigVersion.cmake.in b/KGeoBag/ModuleConfigVersion.cmake.in deleted file mode 100644 index 32d14583a..000000000 --- a/KGeoBag/ModuleConfigVersion.cmake.in +++ /dev/null @@ -1,13 +0,0 @@ -# $Id: ModuleConfigVersion.cmake.in 11916 2012-01-20 18:16:45Z s_voec01 $ - -set(PACKAGE_VERSION "@MODULE_VERSION@") - -# Check whether the requested PACKAGE_FIND_VERSION is compatible -if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") - set(PACKAGE_VERSION_COMPATIBLE FALSE) -else() - set(PACKAGE_VERSION_COMPATIBLE TRUE) - if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") - set(PACKAGE_VERSION_EXACT TRUE) - endif() -endif() \ No newline at end of file diff --git a/KGeoBag/Source/Application/CMakeLists.txt b/KGeoBag/Source/Application/CMakeLists.txt index d70fb3eda..bfaf7da83 100644 --- a/KGeoBag/Source/Application/CMakeLists.txt +++ b/KGeoBag/Source/Application/CMakeLists.txt @@ -1,68 +1,63 @@ -# names -set( APPLICATION_NAMES - KGeoBag - RandomExtensionTester - MetricsExtensionTester - EulerAngles - GeometryDump -) +option (KGeoBag_ENABLE_APP "Build KGeoBag applications" ON) +if (KGeoBag_ENABLE_APP) -# libraries -set( APPLICATION_LIBRARIES - ${Kommon_LIBRARIES} - KGeoBagMath - KGeoBagCore - KGeoBagShapes - KGeoBagAppearance - KGeoBagMesh - KGeoBagAxialMesh - KGeoBagBindings - KGeoBagRandom - KGeoBagMetrics -) -if( KGeoBag_USE_VTK ) - list( APPEND APPLICATION_NAMES - GeometryViewer - MeshViewer - AxialMeshViewer - PointTester - NormalTester - DistanceTester - OutsideTester - RandomPointTester - MeshIntersectionTester - ) - list( APPEND APPLICATION_LIBRARIES - ${Kommon_Vtk_LIBRARIES} - KGeoBagVtkVisualization - ) -endif( KGeoBag_USE_VTK ) + # names + set( APPLICATION_NAMES + KGeoBag + RandomExtensionTester + MetricsExtensionTester + EulerAngles + GeometryDump + ) -if( KGeoBag_USE_ROOT ) - list( APPEND APPLICATION_NAMES - GeometryViewerROOT - ) - list( APPEND APPLICATION_LIBRARIES - KGeoBagROOTVisualization - ) -endif( KGeoBag_USE_ROOT ) + # libraries + set( APPLICATION_LIBRARIES + KGeoBagBindings + KGeoBagCore + KGeoBagRandom + ) -# internal -kasper_internal_include_directories() + if( KGeoBag_USE_VTK ) + list( APPEND APPLICATION_NAMES + GeometryViewer + MeshViewer + AxialMeshViewer + PointTester + NormalTester + DistanceTester + OutsideTester + RandomPointTester + MeshIntersectionTester + ) + list( APPEND APPLICATION_LIBRARIES + KGeoBagVtkVisualization + ) + endif( KGeoBag_USE_VTK ) -# target -if(APPLE) - foreach( NAME ${APPLICATION_NAMES} ) - add_executable( ${NAME} MACOSX_BUNDLE Source/${NAME}.cc ) - endforeach() -else(APPLE) - foreach( NAME ${APPLICATION_NAMES} ) - add_executable( ${NAME} Source/${NAME}.cc ) - endforeach() -endif(APPLE) + if( KGeoBag_USE_ROOT ) + list( APPEND APPLICATION_NAMES + GeometryViewerROOT + ) + list( APPEND APPLICATION_LIBRARIES + KGeoBagROOTVisualization + ) + endif( KGeoBag_USE_ROOT ) -# install -foreach( NAME ${APPLICATION_NAMES} ) - target_link_libraries( ${NAME} ${APPLICATION_LIBRARIES} ) - kasper_install_executables( ${NAME} ) -endforeach() + # target + if(APPLE) + foreach( NAME ${APPLICATION_NAMES} ) + add_executable( ${NAME} MACOSX_BUNDLE Source/${NAME}.cc ) + endforeach() + else(APPLE) + foreach( NAME ${APPLICATION_NAMES} ) + add_executable( ${NAME} Source/${NAME}.cc ) + endforeach() + endif(APPLE) + + # install + foreach( NAME ${APPLICATION_NAMES} ) + target_link_libraries( ${NAME} ${APPLICATION_LIBRARIES} ) + kasper_install_executables( ${NAME} ) + endforeach() + +endif(KGeoBag_ENABLE_APP) diff --git a/KGeoBag/Source/Application/Source/GeometryViewerROOT.cc b/KGeoBag/Source/Application/Source/GeometryViewerROOT.cc index 381376080..ee47defc0 100644 --- a/KGeoBag/Source/Application/Source/GeometryViewerROOT.cc +++ b/KGeoBag/Source/Application/Source/GeometryViewerROOT.cc @@ -11,9 +11,10 @@ using namespace std; int main(int argc, char** argv) { - if (argc < 10) { + if (argc < 2) { cout << "usage: ./GeometryPainterROOT [...] " + << " : ./GeometryPainterROOT [...] --plane={ZX,ZY,XY,XZ,YZ,YX} [--point=''] [--labels=true]" << endl; return -1; } @@ -27,10 +28,54 @@ int main(int argc, char** argv) deque tParameters = tXML.GetArguments().ParameterList(); tParameters.pop_front(); // strip off config file name - vector tPathList; // note 7 more following arguments after paths - while (tParameters.size() > 7) { - tPathList.push_back(tParameters.front()); - tParameters.pop_front(); + KThreeVector tPlaneNormal(0,1,0); // default to yz-plane + KThreeVector tPlanePoint(0,0,0); + bool tSwapAxes = false; + bool tShowLabels = false; + + auto tOptions = tXML.GetArguments().OptionTable(); + if (tOptions.find("plane") != tOptions.end()) { + if (tOptions["plane"] == "ZX" || tOptions["plane"] == "zx") { + tPlaneNormal = KThreeVector(0, 1, 0); + } + else if (tOptions["plane"] == "XZ" || tOptions["plane"] == "xz") { + tPlaneNormal = KThreeVector(0, 1, 0); + tSwapAxes = true; + } + else if (tOptions["plane"] == "YZ" || tOptions["plane"] == "yz") { + tPlaneNormal = KThreeVector(1, 0, 0); + } + else if (tOptions["plane"] == "ZY" || tOptions["plane"] == "zy") { + tPlaneNormal = KThreeVector(1, 0, 0); + tSwapAxes = true; + } + else if (tOptions["plane"] == "YX" || tOptions["plane"] == "yx") { + tPlaneNormal = KThreeVector(0 , 0, 1); + tSwapAxes = true; + } + else if (tOptions["plane"] == "XY" || tOptions["plane"] == "xy") { + tPlaneNormal = KThreeVector(0 , 0, 1); + } + else + coremsg(eError) << "plane definition <" << tOptions["plane"] << "> is not supported" << eom; + } + if (tOptions.find("point") != tOptions.end()) { + istringstream Converter(tOptions["point"]); + Converter >> tPlanePoint; + } + if (tOptions.find("labels") != tOptions.end()) { + tShowLabels = true; + } + + deque tPathList; // note 7 more following arguments after paths + if (tParameters.size() > 7) { + while (tParameters.size() > 7) { + tPathList.push_back(tParameters.front()); + tParameters.pop_front(); + } + } + else { + tPathList = tParameters; } coremsg(eNormal) << "...initialization finished" << eom; @@ -42,6 +87,7 @@ int main(int argc, char** argv) tPainter.SetName("ROOT GeometryPainter"); tPainter.SetDisplayMode(true); tPainter.SetWriteMode(true); + tPainter.SetShowLabels(tShowLabels); if (tParameters.size() >= 3) { string tNormalX(tParameters[0]); @@ -50,9 +96,7 @@ int main(int argc, char** argv) string tSpaceString(" "); string tCombine = tNormalX + tSpaceString + tNormalY + tSpaceString + tNormalZ; istringstream Converter(tCombine); - KThreeVector tPlaneNormal; Converter >> tPlaneNormal; - tPainter.SetPlaneNormal(tPlaneNormal); } if (tParameters.size() >= 6) { @@ -62,20 +106,24 @@ int main(int argc, char** argv) string tSpaceString(" "); string tCombine = tX + tSpaceString + tY + tSpaceString + tZ; istringstream Converter(tCombine); - KThreeVector tPlanePoint; Converter >> tPlanePoint; - tPainter.SetPlanePoint(tPlanePoint); } if (tParameters.size() >= 7) { - if (tParameters[6] == string("true")) { - tPainter.SetSwapAxis(true); + if (tParameters[6] == string("true") || tParameters[6] == string("1")) { + tSwapAxes = true; } - else if (tParameters[6] == string("false")) { - tPainter.SetSwapAxis(false); + else if (tParameters[6] == string("false") || tParameters[6] == string("0")) { + tSwapAxes = false; } } + tPainter.SetPlaneNormal(tPlaneNormal); + tPainter.SetPlanePoint(tPlanePoint); + tPainter.SetSwapAxis(tSwapAxes); + + coremsg(eNormal) << "painting with plane normal " << tPlaneNormal << ", plane point " << tPlanePoint << eom; + for (auto& tPath : tPathList) { for (auto& tSurface : KGInterface::GetInstance()->RetrieveSurfaces(tPath)) { tPainter.AddSurface(tSurface); diff --git a/KGeoBag/Source/Application/Source/MeshIntersectionTester.cc b/KGeoBag/Source/Application/Source/MeshIntersectionTester.cc index 8c6b38da9..038c3188b 100644 --- a/KGeoBag/Source/Application/Source/MeshIntersectionTester.cc +++ b/KGeoBag/Source/Application/Source/MeshIntersectionTester.cc @@ -52,7 +52,7 @@ int main(int argc, char** argv) tTester.SetSampleColor(KGRGBColor(127, 127, 127)); tTester.SetUnintersectedLineColor(KGRGBColor(127, 127, 127)); tTester.SetIntersectedLineColor(KGRGBColor(0, 0, 255)); - tTester.SetVertexSize(0.001); + tTester.SetVertexSize(0.005); tTester.SetLineSize(0.001); for (auto& tPath : tPathList) { diff --git a/KGeoBag/Source/Bindings/CMakeLists.txt b/KGeoBag/Source/Bindings/CMakeLists.txt index eeb5c54ff..da598c785 100644 --- a/KGeoBag/Source/Bindings/CMakeLists.txt +++ b/KGeoBag/Source/Bindings/CMakeLists.txt @@ -1,13 +1,19 @@ # headers set( BINDINGS_HEADER_FILES + + Include/KGBindingsMessage.hh + # math Math/Include/KGTransformationBuilder.hh - + # core Core/Include/KGSurfaceBuilder.hh Core/Include/KGSpaceBuilder.hh Core/Include/KGInterfaceBuilder.hh - + + # External shapes + Shapes/External/Include/KGStlFileBuilder.hh + # complex shapes Shapes/Complex/Include/KGBeamBuilder.hh Shapes/Complex/Include/KGConicalWireArrayBuilder.hh @@ -28,11 +34,11 @@ set( BINDINGS_HEADER_FILES Shapes/PlanarShapes/Include/KGPlanarPolyLineBuilder.hh Shapes/PlanarShapes/Include/KGPlanarCircleBuilder.hh Shapes/PlanarShapes/Include/KGPlanarPolyLoopBuilder.hh - + # flattened closed path surfaces Shapes/FlattenedAreas/Include/KGFlattenedCircleSurfaceBuilder.hh Shapes/FlattenedAreas/Include/KGFlattenedPolyLoopSurfaceBuilder.hh - + # rotated path surfaces Shapes/RotatedAreas/Include/KGRotatedLineSegmentSurfaceBuilder.hh Shapes/RotatedAreas/Include/KGDiskSurfaceBuilder.hh @@ -46,21 +52,21 @@ set( BINDINGS_HEADER_FILES Shapes/RotatedAreas/Include/KGRotatedCircleSurfaceBuilder.hh Shapes/RotatedAreas/Include/KGTorusSurfaceBuilder.hh Shapes/RotatedAreas/Include/KGRotatedPolyLoopSurfaceBuilder.hh - + # shell path surfaces Shapes/ShellAreas/Include/KGShellLineSegmentSurfaceBuilder.hh Shapes/ShellAreas/Include/KGShellArcSegmentSurfaceBuilder.hh Shapes/ShellAreas/Include/KGShellPolyLineSurfaceBuilder.hh Shapes/ShellAreas/Include/KGShellPolyLoopSurfaceBuilder.hh Shapes/ShellAreas/Include/KGShellCircleSurfaceBuilder.hh - + # extruded path surfaces Shapes/ExtrudedAreas/Include/KGExtrudedLineSegmentSurfaceBuilder.hh Shapes/ExtrudedAreas/Include/KGExtrudedArcSegmentSurfaceBuilder.hh Shapes/ExtrudedAreas/Include/KGExtrudedPolyLineSurfaceBuilder.hh Shapes/ExtrudedAreas/Include/KGExtrudedCircleSurfaceBuilder.hh Shapes/ExtrudedAreas/Include/KGExtrudedPolyLoopSurfaceBuilder.hh - + # rotated open path spaces Shapes/RotatedVolumes/Include/KGRotatedLineSegmentSpaceBuilder.hh Shapes/RotatedVolumes/Include/KGCylinderSpaceBuilder.hh @@ -68,19 +74,19 @@ set( BINDINGS_HEADER_FILES Shapes/RotatedVolumes/Include/KGCutConeSpaceBuilder.hh Shapes/RotatedVolumes/Include/KGRotatedArcSegmentSpaceBuilder.hh Shapes/RotatedVolumes/Include/KGRotatedPolyLineSpaceBuilder.hh - - # rotated closed path spaces + + # rotated closed path spaces Shapes/RotatedVolumes/Include/KGRotatedCircleSpaceBuilder.hh Shapes/RotatedVolumes/Include/KGTorusSpaceBuilder.hh Shapes/RotatedVolumes/Include/KGRotatedPolyLoopSpaceBuilder.hh Shapes/RotatedVolumes/Include/KGCylinderTubeSpaceBuilder.hh Shapes/RotatedVolumes/Include/KGCutConeTubeSpaceBuilder.hh - + # extruded closed path spaces Shapes/ExtrudedVolumes/Include/KGExtrudedCircleSpaceBuilder.hh Shapes/ExtrudedVolumes/Include/KGExtrudedPolyLoopSpaceBuilder.hh Shapes/ExtrudedVolumes/Include/KGBoxSpaceBuilder.hh - + # appearance Extensions/Appearance/Include/KGAppearanceBuilder.hh @@ -89,7 +95,7 @@ set( BINDINGS_HEADER_FILES # mesh Extensions/Mesh/Include/KGMeshBuilder.hh - + # axial mesh Extensions/AxialMesh/Include/KGAxialMeshBuilder.hh @@ -100,34 +106,39 @@ set( BINDINGS_HEADER_FILES ) if( KGeoBag_USE_VTK ) - list(APPEND BINDINGS_HEADER_FILES - Visualization/Vtk/Include/KGVTKGeometryPainterBuilder.hh - Visualization/Vtk/Include/KGVTKMeshPainterBuilder.hh - Visualization/Vtk/Include/KGVTKAxialMeshPainterBuilder.hh - Visualization/Vtk/Include/KGVTKPointTesterBuilder.hh - Visualization/Vtk/Include/KGVTKNormalTesterBuilder.hh - Visualization/Vtk/Include/KGVTKDistanceTesterBuilder.hh - Visualization/Vtk/Include/KGVTKOutsideTesterBuilder.hh - Visualization/Vtk/Include/KGVTKRandomPointTesterBuilder.hh - ) + list(APPEND BINDINGS_HEADER_FILES + Visualization/Vtk/Include/KGVTKGeometryPainterBuilder.hh + Visualization/Vtk/Include/KGVTKMeshPainterBuilder.hh + Visualization/Vtk/Include/KGVTKAxialMeshPainterBuilder.hh + Visualization/Vtk/Include/KGVTKPointTesterBuilder.hh + Visualization/Vtk/Include/KGVTKNormalTesterBuilder.hh + Visualization/Vtk/Include/KGVTKDistanceTesterBuilder.hh + Visualization/Vtk/Include/KGVTKOutsideTesterBuilder.hh + Visualization/Vtk/Include/KGVTKRandomPointTesterBuilder.hh + ) endif( KGeoBag_USE_VTK ) if( KGeoBag_USE_ROOT ) - list( APPEND BINDINGS_HEADER_FILES - Visualization/Root/Include/KGROOTGeometryPainterBuilder.hh - ) + list( APPEND BINDINGS_HEADER_FILES + Visualization/Root/Include/KGROOTGeometryPainterBuilder.hh + ) endif( KGeoBag_USE_ROOT ) # sources set( BINDINGS_SOURCE_FILES + Source/KGBindingsMessage.cc + # math Math/Source/KGTransformationBuilder.cc - + # core Core/Source/KGSurfaceBuilder.cc Core/Source/KGSpaceBuilder.cc Core/Source/KGInterfaceBuilder.cc - + + # External shapes + Shapes/External/Source/KGStlFileBuilder.cc + # complex shapes Shapes/Complex/Source/KGBeamBuilder.cc Shapes/Complex/Source/KGConicalWireArrayBuilder.cc @@ -149,10 +160,10 @@ set( BINDINGS_SOURCE_FILES Shapes/PlanarShapes/Source/KGPlanarCircleBuilder.cc Shapes/PlanarShapes/Source/KGPlanarPolyLoopBuilder.cc - # flattened closed path surfaces + # flattened closed path surfaces Shapes/FlattenedAreas/Source/KGFlattenedCircleSurfaceBuilder.cc Shapes/FlattenedAreas/Source/KGFlattenedPolyLoopSurfaceBuilder.cc - + # rotated path surfaces Shapes/RotatedAreas/Source/KGRotatedLineSegmentSurfaceBuilder.cc Shapes/RotatedAreas/Source/KGDiskSurfaceBuilder.cc @@ -166,41 +177,41 @@ set( BINDINGS_SOURCE_FILES Shapes/RotatedAreas/Source/KGRotatedCircleSurfaceBuilder.cc Shapes/RotatedAreas/Source/KGTorusSurfaceBuilder.cc Shapes/RotatedAreas/Source/KGRotatedPolyLoopSurfaceBuilder.cc - + # shell path surfaces Shapes/ShellAreas/Source/KGShellLineSegmentSurfaceBuilder.cc Shapes/ShellAreas/Source/KGShellArcSegmentSurfaceBuilder.cc Shapes/ShellAreas/Source/KGShellPolyLineSurfaceBuilder.cc Shapes/ShellAreas/Source/KGShellPolyLoopSurfaceBuilder.cc Shapes/ShellAreas/Source/KGShellCircleSurfaceBuilder.cc - + # extruded path surfaces Shapes/ExtrudedAreas/Source/KGExtrudedLineSegmentSurfaceBuilder.cc Shapes/ExtrudedAreas/Source/KGExtrudedArcSegmentSurfaceBuilder.cc Shapes/ExtrudedAreas/Source/KGExtrudedPolyLineSurfaceBuilder.cc Shapes/ExtrudedAreas/Source/KGExtrudedCircleSurfaceBuilder.cc Shapes/ExtrudedAreas/Source/KGExtrudedPolyLoopSurfaceBuilder.cc - + # rotated open path spaces - Shapes/RotatedVolumes/Source/KGRotatedLineSegmentSpaceBuilder.cc + Shapes/RotatedVolumes/Source/KGRotatedLineSegmentSpaceBuilder.cc Shapes/RotatedVolumes/Source/KGCylinderSpaceBuilder.cc Shapes/RotatedVolumes/Source/KGConeSpaceBuilder.cc Shapes/RotatedVolumes/Source/KGCutConeSpaceBuilder.cc Shapes/RotatedVolumes/Source/KGRotatedArcSegmentSpaceBuilder.cc Shapes/RotatedVolumes/Source/KGRotatedPolyLineSpaceBuilder.cc - + # rotated closed path spaces Shapes/RotatedVolumes/Source/KGRotatedCircleSpaceBuilder.cc Shapes/RotatedVolumes/Source/KGTorusSpaceBuilder.cc Shapes/RotatedVolumes/Source/KGRotatedPolyLoopSpaceBuilder.cc Shapes/RotatedVolumes/Source/KGCylinderTubeSpaceBuilder.cc Shapes/RotatedVolumes/Source/KGCutConeTubeSpaceBuilder.cc - + # extruded closed path spaces Shapes/ExtrudedVolumes/Source/KGExtrudedCircleSpaceBuilder.cc Shapes/ExtrudedVolumes/Source/KGExtrudedPolyLoopSpaceBuilder.cc Shapes/ExtrudedVolumes/Source/KGBoxSpaceBuilder.cc - + # appearance Extensions/Appearance/Source/KGAppearanceBuilder.cc @@ -209,7 +220,7 @@ set( BINDINGS_SOURCE_FILES # mesh Extensions/Mesh/Source/KGMeshBuilder.cc - + # axial mesh Extensions/AxialMesh/Source/KGAxialMeshBuilder.cc @@ -220,88 +231,67 @@ set( BINDINGS_SOURCE_FILES ) if( KGeoBag_USE_VTK ) - list( APPEND BINDINGS_SOURCE_FILES - Visualization/Vtk/Source/KGVTKGeometryPainterBuilder.cc - Visualization/Vtk/Source/KGVTKMeshPainterBuilder.cc - Visualization/Vtk/Source/KGVTKAxialMeshPainterBuilder.cc - Visualization/Vtk/Source/KGVTKPointTesterBuilder.cc - Visualization/Vtk/Source/KGVTKNormalTesterBuilder.cc - Visualization/Vtk/Source/KGVTKDistanceTesterBuilder.cc - Visualization/Vtk/Source/KGVTKOutsideTesterBuilder.cc - Visualization/Vtk/Source/KGVTKRandomPointTesterBuilder.cc - ) -endif( KGeoBag_USE_VTK ) - -if( KGeoBag_USE_ROOT ) - list( APPEND BINDINGS_SOURCE_FILES - Visualization/Root/Source/KGROOTGeometryPainterBuilder.cc - ) -endif( KGeoBag_USE_ROOT ) - -# internal -kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Math/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Core/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Shapes/Complex/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Shapes/PlanarShapes/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Shapes/FlattenedAreas/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Shapes/RotatedAreas/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Shapes/RotatedVolumes/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Shapes/ExtrudedAreas/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Shapes/ExtrudedVolumes/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Shapes/ShellAreas/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Extensions/Appearance/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Extensions/Deformation/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Extensions/Mesh/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Extensions/AxialMesh/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Extensions/DiscreteRotationalMesh/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Visualization/Basic/Include -) - -if( KGeoBag_USE_VTK ) - kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Visualization/Vtk/Include - ) + list( APPEND BINDINGS_SOURCE_FILES + Visualization/Vtk/Source/KGVTKGeometryPainterBuilder.cc + Visualization/Vtk/Source/KGVTKMeshPainterBuilder.cc + Visualization/Vtk/Source/KGVTKAxialMeshPainterBuilder.cc + Visualization/Vtk/Source/KGVTKPointTesterBuilder.cc + Visualization/Vtk/Source/KGVTKNormalTesterBuilder.cc + Visualization/Vtk/Source/KGVTKDistanceTesterBuilder.cc + Visualization/Vtk/Source/KGVTKOutsideTesterBuilder.cc + Visualization/Vtk/Source/KGVTKRandomPointTesterBuilder.cc + ) endif( KGeoBag_USE_VTK ) if( KGeoBag_USE_ROOT ) - kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Visualization/Root/Include - ) + list( APPEND BINDINGS_SOURCE_FILES + Visualization/Root/Source/KGROOTGeometryPainterBuilder.cc + ) endif( KGeoBag_USE_ROOT ) # target add_library( KGeoBagBindings SHARED - ${BINDINGS_SOURCE_FILES} ${BINDINGS_HEADER_FILES} + ${BINDINGS_SOURCE_FILES} ${BINDINGS_HEADER_FILES} ) -set( BINDINGS_LIBRARIES - ${Kommon_LIBRARIES} - KGeoBagCore - KGeoBagShapes - KGeoBagAppearance - KGeoBagDeformation - KGeoBagMesh - KGeoBagAxialMesh - KGeoBagDiscreteRotationalMesh - KGeoBagBasicVisualization +add_library( KGeoBagBindingsHeaders INTERFACE ) + +foreach(HEADER ${BINDINGS_HEADER_FILES}) + get_filename_component(DIRNAME ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER} DIRECTORY) + target_include_directories(KGeoBagBindings PUBLIC $) + target_include_directories(KGeoBagBindingsHeaders INTERFACE $) +endforeach(HEADER) +target_include_directories(KGeoBagBindings PUBLIC $) + +target_link_libraries( KGeoBagBindings + PUBLIC + Kommon + KGeoBagCore + KGeoBagShapes + KGeoBagAppearance + KGeoBagDeformation + KGeoBagMetrics + KGeoBagRandom + KGeoBagMesh + KGeoBagAxialMesh + KGeoBagDiscreteRotationalMesh + KGeoBagBasicVisualization ) if( KGeoBag_USE_VTK ) - list( APPEND BINDINGS_LIBRARIES - KGeoBagVtkVisualization - ) + target_link_libraries( KGeoBagBindings + PUBLIC + KommonVtk + KGeoBagVtkVisualization + ) endif( KGeoBag_USE_VTK ) if( KGeoBag_USE_ROOT ) - list( APPEND BINDINGS_LIBRARIES - KGeoBagROOTVisualization - ) + target_link_libraries( KGeoBagBindings + PUBLIC + KGeoBagROOTVisualization + ) endif( KGeoBag_USE_ROOT ) -target_link_libraries( KGeoBagBindings - ${BINDINGS_LIBRARIES} -) - # install kasper_install_headers( ${BINDINGS_HEADER_FILES} ) -kasper_install_libraries( KGeoBagBindings ) +kasper_install_libraries( KGeoBagBindings KGeoBagBindingsHeaders ) diff --git a/KGeoBag/Source/Bindings/Extensions/Appearance/Include/KGAppearanceBuilder.hh b/KGeoBag/Source/Bindings/Extensions/Appearance/Include/KGAppearanceBuilder.hh index 1ce0633bc..5cb9e259c 100644 --- a/KGeoBag/Source/Bindings/Extensions/Appearance/Include/KGAppearanceBuilder.hh +++ b/KGeoBag/Source/Bindings/Extensions/Appearance/Include/KGAppearanceBuilder.hh @@ -2,6 +2,7 @@ #define KGAPPEARANCEBUILDER_HH_ #include "KGAppearance.hh" +#include "KGBindingsMessage.hh" namespace KGeoBag { @@ -53,7 +54,7 @@ template<> inline bool KGAppearanceBuilder::AddAttribute(KContainer* aContainer) KGSurface* tSurface; if (tSurfaces.size() == 0) { - coremsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } @@ -69,7 +70,7 @@ template<> inline bool KGAppearanceBuilder::AddAttribute(KContainer* aContainer) KGSpace* tSpace; if (tSpaces.size() == 0) { - coremsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } diff --git a/KGeoBag/Source/Bindings/Extensions/AxialMesh/Include/KGAxialMeshBuilder.hh b/KGeoBag/Source/Bindings/Extensions/AxialMesh/Include/KGAxialMeshBuilder.hh index 2b996c819..6ccca18e2 100644 --- a/KGeoBag/Source/Bindings/Extensions/AxialMesh/Include/KGAxialMeshBuilder.hh +++ b/KGeoBag/Source/Bindings/Extensions/AxialMesh/Include/KGAxialMeshBuilder.hh @@ -2,6 +2,7 @@ #define KGAXIALMESHBUILDER_HH_ #include "KGAxialMesh.hh" +#include "KGBindingsMessage.hh" namespace KGeoBag { @@ -45,7 +46,7 @@ template<> inline bool KGAxialMeshBuilder::AddAttribute(KContainer* aContainer) KGSurface* tSurface; if (tSurfaces.size() == 0) { - coremsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } @@ -61,7 +62,7 @@ template<> inline bool KGAxialMeshBuilder::AddAttribute(KContainer* aContainer) KGSpace* tSpace; if (tSpaces.size() == 0) { - coremsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } diff --git a/KGeoBag/Source/Bindings/Extensions/Deformation/Include/KGMeshDeformerBuilder.hh b/KGeoBag/Source/Bindings/Extensions/Deformation/Include/KGMeshDeformerBuilder.hh index ec0fe8649..800e7fe09 100644 --- a/KGeoBag/Source/Bindings/Extensions/Deformation/Include/KGMeshDeformerBuilder.hh +++ b/KGeoBag/Source/Bindings/Extensions/Deformation/Include/KGMeshDeformerBuilder.hh @@ -3,6 +3,7 @@ #include "KComplexElement.hh" #include "KGMeshDeformer.hh" +#include "KGBindingsMessage.hh" namespace katrin { @@ -20,7 +21,7 @@ template<> inline bool KGMeshDeformerBuilder::AddAttribute(KContainer* aContaine KGSurface* tSurface; if (tSurfaces.size() == 0) { - coremsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } @@ -36,7 +37,7 @@ template<> inline bool KGMeshDeformerBuilder::AddAttribute(KContainer* aContaine KGSpace* tSpace; if (tSpaces.size() == 0) { - coremsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } diff --git a/KGeoBag/Source/Bindings/Extensions/DiscreteRotationalMesh/Include/KGDiscreteRotationalMeshBuilder.hh b/KGeoBag/Source/Bindings/Extensions/DiscreteRotationalMesh/Include/KGDiscreteRotationalMeshBuilder.hh index ba28710b3..f17e0b0ca 100644 --- a/KGeoBag/Source/Bindings/Extensions/DiscreteRotationalMesh/Include/KGDiscreteRotationalMeshBuilder.hh +++ b/KGeoBag/Source/Bindings/Extensions/DiscreteRotationalMesh/Include/KGDiscreteRotationalMeshBuilder.hh @@ -2,6 +2,7 @@ #define KGDISCRETEROTATIONALMESHBUILDER_HH_ #include "KGDiscreteRotationalMesh.hh" +#include "KGBindingsMessage.hh" namespace KGeoBag { @@ -67,7 +68,7 @@ template<> inline bool KGDiscreteRotationalMeshBuilder::AddAttribute(KContainer* KGSurface* tSurface; if (tSurfaces.size() == 0) { - coremsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } @@ -83,7 +84,7 @@ template<> inline bool KGDiscreteRotationalMeshBuilder::AddAttribute(KContainer* KGSpace* tSpace; if (tSpaces.size() == 0) { - coremsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } diff --git a/KGeoBag/Source/Bindings/Extensions/Mesh/Include/KGMeshBuilder.hh b/KGeoBag/Source/Bindings/Extensions/Mesh/Include/KGMeshBuilder.hh index 3b093f966..310a38898 100644 --- a/KGeoBag/Source/Bindings/Extensions/Mesh/Include/KGMeshBuilder.hh +++ b/KGeoBag/Source/Bindings/Extensions/Mesh/Include/KGMeshBuilder.hh @@ -2,6 +2,7 @@ #define KGMESHERBUILDER_HH_ #include "KGMesh.hh" +#include "KGBindingsMessage.hh" namespace KGeoBag { @@ -45,7 +46,7 @@ template<> inline bool KGMeshBuilder::AddAttribute(KContainer* aContainer) KGSurface* tSurface; if (tSurfaces.size() == 0) { - coremsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } @@ -61,7 +62,7 @@ template<> inline bool KGMeshBuilder::AddAttribute(KContainer* aContainer) KGSpace* tSpace; if (tSpaces.size() == 0) { - coremsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } diff --git a/KGeoBag/Source/Bindings/Extensions/Mesh/Source/KGMeshBuilder.cc b/KGeoBag/Source/Bindings/Extensions/Mesh/Source/KGMeshBuilder.cc index 877e8aabf..6f55e2a1f 100644 --- a/KGeoBag/Source/Bindings/Extensions/Mesh/Source/KGMeshBuilder.cc +++ b/KGeoBag/Source/Bindings/Extensions/Mesh/Source/KGMeshBuilder.cc @@ -14,6 +14,8 @@ KGMeshAttributor::~KGMeshAttributor() { KGMesher tMesher; + coremsg(eNormal) << "Generating mesh for <" << fSurfaces.size() << "> surfaces and <" << fSpaces.size() << "> spaces ..." << eom; + KGMeshSurface* tMeshSurface; for (auto& surface : fSurfaces) { tMeshSurface = surface->MakeExtension(); diff --git a/KGeoBag/Source/Bindings/Include/KGBindingsMessage.hh b/KGeoBag/Source/Bindings/Include/KGBindingsMessage.hh new file mode 100644 index 000000000..3ec600ca4 --- /dev/null +++ b/KGeoBag/Source/Bindings/Include/KGBindingsMessage.hh @@ -0,0 +1,18 @@ +#ifndef KGBINDINGSMESSAGE_HH_ +#define KGBINDINGSMESSAGE_HH_ + +#include "KMessage.h" + +KMESSAGE_DECLARE(KGeoBag, bindmsg) + +#ifdef KGeoBag_ENABLE_DEBUG + +#define bindmsg_DEBUG(xCONTENT) bindmsg(eDebug) << xCONTENT; + +#endif + +#ifndef bindmsg_DEBUG +#define bindmsg_DEBUG(xCONTENT) +#endif + +#endif diff --git a/KGeoBag/Source/Bindings/Shapes/Complex/Include/KGExtrudedObjectBuilder.hh b/KGeoBag/Source/Bindings/Shapes/Complex/Include/KGExtrudedObjectBuilder.hh index 2600d1609..c9b2ed609 100644 --- a/KGeoBag/Source/Bindings/Shapes/Complex/Include/KGExtrudedObjectBuilder.hh +++ b/KGeoBag/Source/Bindings/Shapes/Complex/Include/KGExtrudedObjectBuilder.hh @@ -108,6 +108,22 @@ template<> inline bool KGExtrudedObjectBuilder::AddAttribute(KContainer* anAttri anAttribute->CopyTo(fObject, &KGExtrudedObject::SetDiscretizationPower); return true; } + if (anAttribute->GetName() == "extruded_mesh_count") { + anAttribute->CopyTo(fObject, &KGExtrudedObject::SetExtrudedMeshCount); + return true; + } + if (anAttribute->GetName() == "extruded_mesh_power") { + anAttribute->CopyTo(fObject, &KGExtrudedObject::SetExtrudedMeshPower); + return true; + } + if (anAttribute->GetName() == "refine_mesh") { + anAttribute->CopyTo(fObject, &KGExtrudedObject::SetRefineMesh); + return true; + } + if (anAttribute->GetName() == "mesh_merge_distance") { + anAttribute->CopyTo(fObject, &KGExtrudedObject::SetMeshMergeDistance); + return true; + } if (anAttribute->GetName() == "closed_form") { bool closedLoops = true; anAttribute->CopyTo(closedLoops); diff --git a/KGeoBag/Source/Bindings/Shapes/Complex/Source/KGExtrudedObjectBuilder.cc b/KGeoBag/Source/Bindings/Shapes/Complex/Source/KGExtrudedObjectBuilder.cc index 54b32ac34..0056b19d6 100644 --- a/KGeoBag/Source/Bindings/Shapes/Complex/Source/KGExtrudedObjectBuilder.cc +++ b/KGeoBag/Source/Bindings/Shapes/Complex/Source/KGExtrudedObjectBuilder.cc @@ -22,6 +22,10 @@ STATICINT sKGExtrudedObjectBuilderStructure = KGExtrudedObjectBuilder::Attribute("z_min") + KGExtrudedObjectBuilder::Attribute("z_max") + KGExtrudedObjectBuilder::Attribute("longitudinal_mesh_count") + KGExtrudedObjectBuilder::Attribute("longitudinal_mesh_power") + + KGExtrudedObjectBuilder::Attribute("extruded_mesh_count") + + KGExtrudedObjectBuilder::Attribute("extruded_mesh_power") + + KGExtrudedObjectBuilder::Attribute("refine_mesh") + + KGExtrudedObjectBuilder::Attribute("mesh_merge_distance") + KGExtrudedObjectBuilder::Attribute("closed_form") + KGExtrudedObjectBuilder::ComplexElement("outer_line") + KGExtrudedObjectBuilder::ComplexElement("inner_line") + diff --git a/KGeoBag/Source/Bindings/Shapes/External/Include/KGStlFileBuilder.hh b/KGeoBag/Source/Bindings/Shapes/External/Include/KGStlFileBuilder.hh new file mode 100644 index 000000000..4c3e5e3b4 --- /dev/null +++ b/KGeoBag/Source/Bindings/Shapes/External/Include/KGStlFileBuilder.hh @@ -0,0 +1,114 @@ +/** + * @file KGStlFileBuilder.hh + * @author Jan Behrens + * @date 2021-07-02 + */ + +#ifndef KGSTLFILEBUILDER_HH_ +#define KGSTLFILEBUILDER_HH_ + +#include "KComplexElement.hh" +#include "KContainer.hh" +#include "KGWrappedSurface.hh" +#include "KGWrappedSpace.hh" +#include "KGStlFile.hh" + +using namespace KGeoBag; + +namespace katrin +{ + +using KGStlFileBuilder = KComplexElement; + +template<> inline bool KGStlFileBuilder::AddAttribute(KContainer* anAttribute) +{ + if (anAttribute->GetName() == "file") { + anAttribute->CopyTo(fObject, &KGStlFile::SetFile); + return true; + } + if (anAttribute->GetName() == "path") { + anAttribute->CopyTo(fObject, &KGStlFile::SetPath); + return true; + } + if (anAttribute->GetName() == "mesh_count") { + anAttribute->CopyTo(fObject, &KGStlFile::SetNDisc); + return true; + } + if (anAttribute->GetName() == "scale") { + anAttribute->CopyTo(fObject, &KGStlFile::SetScaleFactor); + return true; + } + if (anAttribute->GetName() == "selector") { + // allowed syntax pattern: "a-b;c-d;..." + for (auto & sel : KStringUtils::SplitBySingleDelim(anAttribute->AsString(), ";")) { + size_t pos = sel.find_first_of("-"); + size_t first = 0, last = 0; + if (pos == std::string::npos) { + if (KStringUtils::Convert(sel, first)) + fObject->SelectCell(first); + } + else { + if (! KStringUtils::Convert(sel.substr(0, pos), first)) + first = 0; + if (! KStringUtils::Convert(sel.substr(pos+1), last)) + last = std::numeric_limits::max(); + fObject->SelectCellRange(first, last); + } + } + return true; + } + return false; +} + +using KGStlFileSurfaceBuilder = KComplexElement>; + +template<> inline bool KGStlFileSurfaceBuilder::AddAttribute(KContainer* anAttribute) +{ + if (anAttribute->GetName() == "name") { + anAttribute->CopyTo(fObject, &KGWrappedSurface::SetName); + return true; + } + return false; +} + +template<> inline bool KGStlFileSurfaceBuilder::AddElement(KContainer* anElement) +{ + if (anElement->GetName() == "stl_file") { + KGStlFile* object = nullptr; + anElement->ReleaseTo(object); + object->Initialize(); + std::shared_ptr smartPtr(object); + fObject->SetObject(smartPtr); + return true; + } + return false; +} + + +using KGStlFileSpaceBuilder = KComplexElement>; + +template<> inline bool KGStlFileSpaceBuilder::AddAttribute(KContainer* anAttribute) +{ + if (anAttribute->GetName() == "name") { + anAttribute->CopyTo(fObject, &KGWrappedSpace::SetName); + return true; + } + return false; +} + +template<> inline bool KGStlFileSpaceBuilder::AddElement(KContainer* anElement) +{ + if (anElement->GetName() == "stl_file") { + KGStlFile* object = nullptr; + anElement->ReleaseTo(object); + object->Initialize(); + std::shared_ptr smartPtr(object); + fObject->SetObject(smartPtr); + return true; + } + return false; +} + +} // namespace katrin + +#endif // KGSTLFILEBUILDER_HH_ diff --git a/KGeoBag/Source/Bindings/Shapes/External/Source/KGStlFileBuilder.cc b/KGeoBag/Source/Bindings/Shapes/External/Source/KGStlFileBuilder.cc new file mode 100644 index 000000000..069552939 --- /dev/null +++ b/KGeoBag/Source/Bindings/Shapes/External/Source/KGStlFileBuilder.cc @@ -0,0 +1,35 @@ +/** + * @file KGStlFileBuilder.cc + * @author Jan Behrens + * @date 2021-07-02 + */ + +#include "KGStlFileBuilder.hh" +#include "KGInterfaceBuilder.hh" + +using namespace KGeoBag; +using namespace std; + +namespace katrin +{ + +STATICINT sKGStlFileBuilderStructure = + KGStlFileBuilder::Attribute("file") + + KGStlFileBuilder::Attribute("path") + + KGStlFileBuilder::Attribute("mesh_count") + + KGStlFileBuilder::Attribute("scale") + + KGStlFileBuilder::Attribute("selector"); + +STATICINT sKGStlFileSurfaceBuilderStructure = + KGStlFileSurfaceBuilder::Attribute("name") + + KGStlFileSurfaceBuilder::ComplexElement("stl_file"); + +STATICINT sKGStlFileSurfaceBuilder = KGInterfaceBuilder::ComplexElement>("stl_file_surface"); + +STATICINT sKGStlFileSpaceBuilderStructure = + KGStlFileSpaceBuilder::Attribute("name") + + KGStlFileSpaceBuilder::ComplexElement("stl_file"); + +STATICINT sKGStlFileSpaceBuilder = KGInterfaceBuilder::ComplexElement>("stl_file_space"); + +} // namespace katrin diff --git a/KGeoBag/Source/Bindings/Source/KGBindingsMessage.cc b/KGeoBag/Source/Bindings/Source/KGBindingsMessage.cc new file mode 100644 index 000000000..a3a809551 --- /dev/null +++ b/KGeoBag/Source/Bindings/Source/KGBindingsMessage.cc @@ -0,0 +1,3 @@ +#include "KGBindingsMessage.hh" + +KMESSAGE_DEFINE(KGeoBag, bindmsg, kg_bindings, KGBINDINGS) diff --git a/KGeoBag/Source/Bindings/Visualization/Basic/Include/KGGeometryPrinterBuilder.hh b/KGeoBag/Source/Bindings/Visualization/Basic/Include/KGGeometryPrinterBuilder.hh index 47798dab8..4f9f9f41e 100644 --- a/KGeoBag/Source/Bindings/Visualization/Basic/Include/KGGeometryPrinterBuilder.hh +++ b/KGeoBag/Source/Bindings/Visualization/Basic/Include/KGGeometryPrinterBuilder.hh @@ -3,7 +3,7 @@ #include "KComplexElement.hh" #include "KGGeometryPrinter.hh" -#include "KGVisualizationMessage.hh" +#include "KGBindingsMessage.hh" namespace katrin { @@ -45,7 +45,7 @@ template<> inline bool KGGeometryPrinterBuilder::AddAttribute(KContainer* aConta KGSurface* tSurface; if (tSurfaces.size() == 0) { - coremsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } @@ -65,7 +65,7 @@ template<> inline bool KGGeometryPrinterBuilder::AddAttribute(KContainer* aConta KGSpace* tSpace; if (tSpaces.size() == 0) { - coremsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } diff --git a/KGeoBag/Source/Bindings/Visualization/Root/Include/KGROOTGeometryPainterBuilder.hh b/KGeoBag/Source/Bindings/Visualization/Root/Include/KGROOTGeometryPainterBuilder.hh index f92790514..ad7feee2c 100644 --- a/KGeoBag/Source/Bindings/Visualization/Root/Include/KGROOTGeometryPainterBuilder.hh +++ b/KGeoBag/Source/Bindings/Visualization/Root/Include/KGROOTGeometryPainterBuilder.hh @@ -3,7 +3,7 @@ #include "KComplexElement.hh" #include "KGROOTGeometryPainter.hh" -#include "KGVisualizationMessage.hh" +#include "KGBindingsMessage.hh" namespace katrin { @@ -37,7 +37,7 @@ template<> inline bool KGROOTGeometryPainterBuilder::AddAttribute(KContainer* aC KGSurface* tSurface; if (tSurfaces.size() == 0) { - coremsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } @@ -57,7 +57,7 @@ template<> inline bool KGROOTGeometryPainterBuilder::AddAttribute(KContainer* aC KGSpace* tSpace; if (tSpaces.size() == 0) { - coremsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } @@ -67,6 +67,18 @@ template<> inline bool KGROOTGeometryPainterBuilder::AddAttribute(KContainer* aC } return true; } + if (aContainer->GetName() == "save_json") { + aContainer->CopyTo(fObject, &KGROOTGeometryPainter::SetSaveJSON); + return true; + } + if (aContainer->GetName() == "save_svg") { + aContainer->CopyTo(fObject, &KGROOTGeometryPainter::SetSaveSVG); + return true; + } + if (aContainer->GetName() == "show_labels") { + aContainer->CopyTo(fObject, &KGROOTGeometryPainter::SetShowLabels); + return true; + } if (aContainer->GetName() == "plane_normal") { aContainer->CopyTo(fObject, &KGROOTGeometryPainter::SetPlaneNormal); return true; diff --git a/KGeoBag/Source/Bindings/Visualization/Root/Source/KGROOTGeometryPainterBuilder.cc b/KGeoBag/Source/Bindings/Visualization/Root/Source/KGROOTGeometryPainterBuilder.cc index 7442169cd..a81fc3ca1 100644 --- a/KGeoBag/Source/Bindings/Visualization/Root/Source/KGROOTGeometryPainterBuilder.cc +++ b/KGeoBag/Source/Bindings/Visualization/Root/Source/KGROOTGeometryPainterBuilder.cc @@ -14,6 +14,9 @@ STATICINT sKGROOTGeometryPainterStructure = KGROOTGeometryPainterBuilder::Attrib KGROOTGeometryPainterBuilder::Attribute("path") + KGROOTGeometryPainterBuilder::Attribute("surfaces") + KGROOTGeometryPainterBuilder::Attribute("spaces") + + KGROOTGeometryPainterBuilder::Attribute("show_labels") + + KGROOTGeometryPainterBuilder::Attribute("save_json") + + KGROOTGeometryPainterBuilder::Attribute("save_svg") + KGROOTGeometryPainterBuilder::Attribute("plane_normal") + KGROOTGeometryPainterBuilder::Attribute("plane_point") + KGROOTGeometryPainterBuilder::Attribute("swap_axis") + diff --git a/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKAxialMeshPainterBuilder.hh b/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKAxialMeshPainterBuilder.hh index e2d7dda4a..71f9f792a 100644 --- a/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKAxialMeshPainterBuilder.hh +++ b/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKAxialMeshPainterBuilder.hh @@ -3,7 +3,7 @@ #include "KComplexElement.hh" #include "KGVTKAxialMeshPainter.hh" -#include "KGVisualizationMessage.hh" +#include "KGBindingsMessage.hh" namespace katrin { @@ -43,7 +43,7 @@ template<> inline bool KGVTKAxialMeshPainterBuilder::AddAttribute(KContainer* aC return true; } - coremsg(eWarning) << "unknown option <" << tMode << "> for vtk mesh painter color mode" << eom; + bindmsg(eWarning) << "unknown option <" << tMode << "> for vtk mesh painter color mode" << eom; return false; } if (aContainer->GetName() == "surfaces") { @@ -56,7 +56,7 @@ template<> inline bool KGVTKAxialMeshPainterBuilder::AddAttribute(KContainer* aC KGSurface* tSurface; if (tSurfaces.size() == 0) { - coremsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } @@ -76,7 +76,7 @@ template<> inline bool KGVTKAxialMeshPainterBuilder::AddAttribute(KContainer* aC KGSpace* tSpace; if (tSpaces.size() == 0) { - coremsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } diff --git a/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKDistanceTesterBuilder.hh b/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKDistanceTesterBuilder.hh index 9f5f9e04e..6cdb2f5a7 100644 --- a/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKDistanceTesterBuilder.hh +++ b/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKDistanceTesterBuilder.hh @@ -3,7 +3,7 @@ #include "KComplexElement.hh" #include "KGVTKDistanceTester.hh" -#include "KGVisualizationMessage.hh" +#include "KGBindingsMessage.hh" namespace katrin { @@ -29,7 +29,7 @@ template<> inline bool KGVTKDistanceTesterBuilder::AddAttribute(KContainer* aCon KGSurface* tSurface; if (tSurfaces.size() == 0) { - coremsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } @@ -49,7 +49,7 @@ template<> inline bool KGVTKDistanceTesterBuilder::AddAttribute(KContainer* aCon KGSpace* tSpace; if (tSpaces.size() == 0) { - coremsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } diff --git a/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKGeometryPainterBuilder.hh b/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKGeometryPainterBuilder.hh index acad13b65..b5ba9b077 100644 --- a/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKGeometryPainterBuilder.hh +++ b/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKGeometryPainterBuilder.hh @@ -3,7 +3,7 @@ #include "KComplexElement.hh" #include "KGVTKGeometryPainter.hh" -#include "KGVisualizationMessage.hh" +#include "KGBindingsMessage.hh" namespace katrin { @@ -41,7 +41,7 @@ template<> inline bool KGVTKGeometryPainterBuilder::AddAttribute(KContainer* aCo KGSurface* tSurface; if (tSurfaces.size() == 0) { - coremsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } @@ -61,7 +61,7 @@ template<> inline bool KGVTKGeometryPainterBuilder::AddAttribute(KContainer* aCo KGSpace* tSpace; if (tSpaces.size() == 0) { - coremsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } diff --git a/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKMeshPainterBuilder.hh b/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKMeshPainterBuilder.hh index 7f8f2e20f..fca967b0f 100644 --- a/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKMeshPainterBuilder.hh +++ b/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKMeshPainterBuilder.hh @@ -3,7 +3,7 @@ #include "KComplexElement.hh" #include "KGVTKMeshPainter.hh" -#include "KGVisualizationMessage.hh" +#include "KGBindingsMessage.hh" namespace katrin { @@ -43,7 +43,7 @@ template<> inline bool KGVTKMeshPainterBuilder::AddAttribute(KContainer* aContai return true; } - coremsg(eWarning) << "unknown option <" << tMode << "> for vtk mesh painter color mode" << eom; + bindmsg(eWarning) << "unknown option <" << tMode << "> for vtk mesh painter color mode" << eom; return false; } if (aContainer->GetName() == "surfaces") { @@ -56,7 +56,7 @@ template<> inline bool KGVTKMeshPainterBuilder::AddAttribute(KContainer* aContai KGSurface* tSurface; if (tSurfaces.size() == 0) { - coremsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } @@ -76,7 +76,7 @@ template<> inline bool KGVTKMeshPainterBuilder::AddAttribute(KContainer* aContai KGSpace* tSpace; if (tSpaces.size() == 0) { - coremsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } diff --git a/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKNormalTesterBuilder.hh b/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKNormalTesterBuilder.hh index 5337e7a2e..2887cdbb2 100644 --- a/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKNormalTesterBuilder.hh +++ b/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKNormalTesterBuilder.hh @@ -3,7 +3,7 @@ #include "KComplexElement.hh" #include "KGVTKNormalTester.hh" -#include "KGVisualizationMessage.hh" +#include "KGBindingsMessage.hh" namespace katrin { @@ -29,7 +29,7 @@ template<> inline bool KGVTKNormalTesterBuilder::AddAttribute(KContainer* aConta KGSurface* tSurface; if (tSurfaces.size() == 0) { - coremsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } @@ -49,7 +49,7 @@ template<> inline bool KGVTKNormalTesterBuilder::AddAttribute(KContainer* aConta KGSpace* tSpace; if (tSpaces.size() == 0) { - coremsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } diff --git a/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKOutsideTesterBuilder.hh b/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKOutsideTesterBuilder.hh index d03dc9979..fc3d7e23e 100644 --- a/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKOutsideTesterBuilder.hh +++ b/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKOutsideTesterBuilder.hh @@ -3,7 +3,7 @@ #include "KComplexElement.hh" #include "KGVTKOutsideTester.hh" -#include "KGVisualizationMessage.hh" +#include "KGBindingsMessage.hh" namespace katrin { @@ -29,7 +29,7 @@ template<> inline bool KGVTKOutsideTesterBuilder::AddAttribute(KContainer* aCont KGSurface* tSurface; if (tSurfaces.size() == 0) { - coremsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } @@ -49,7 +49,7 @@ template<> inline bool KGVTKOutsideTesterBuilder::AddAttribute(KContainer* aCont KGSpace* tSpace; if (tSpaces.size() == 0) { - coremsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } diff --git a/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKPointTesterBuilder.hh b/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKPointTesterBuilder.hh index 26f5ac006..9d28bb7a0 100644 --- a/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKPointTesterBuilder.hh +++ b/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKPointTesterBuilder.hh @@ -3,7 +3,7 @@ #include "KComplexElement.hh" #include "KGVTKPointTester.hh" -#include "KGVisualizationMessage.hh" +#include "KGBindingsMessage.hh" namespace katrin { @@ -29,7 +29,7 @@ template<> inline bool KGVTKPointTesterBuilder::AddAttribute(KContainer* aContai KGSurface* tSurface; if (tSurfaces.size() == 0) { - coremsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } @@ -49,7 +49,7 @@ template<> inline bool KGVTKPointTesterBuilder::AddAttribute(KContainer* aContai KGSpace* tSpace; if (tSpaces.size() == 0) { - coremsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } diff --git a/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKRandomPointTesterBuilder.hh b/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKRandomPointTesterBuilder.hh index 44426b7c8..7696de477 100644 --- a/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKRandomPointTesterBuilder.hh +++ b/KGeoBag/Source/Bindings/Visualization/Vtk/Include/KGVTKRandomPointTesterBuilder.hh @@ -3,7 +3,7 @@ #include "KComplexElement.hh" #include "KGVTKRandomPointTester.hh" -#include "KGVisualizationMessage.hh" +#include "KGBindingsMessage.hh" namespace katrin { @@ -29,7 +29,7 @@ template<> inline bool KGVTKRandomPointTesterBuilder::AddAttribute(KContainer* a KGSurface* tSurface; if (tSurfaces.size() == 0) { - coremsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no surfaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } @@ -49,7 +49,7 @@ template<> inline bool KGVTKRandomPointTesterBuilder::AddAttribute(KContainer* a KGSpace* tSpace; if (tSpaces.size() == 0) { - coremsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; + bindmsg(eWarning) << "no spaces found for specifier <" << aContainer->AsString() << ">" << eom; return true; } diff --git a/KGeoBag/Source/Core/CMakeLists.txt b/KGeoBag/Source/Core/CMakeLists.txt index 414cef585..22b9d45e8 100644 --- a/KGeoBag/Source/Core/CMakeLists.txt +++ b/KGeoBag/Source/Core/CMakeLists.txt @@ -30,19 +30,31 @@ set( CORE_SOURCE_FILES Source/KGInterface.cc ) -# internal -kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Include -) - # target add_library( KGeoBagCore SHARED - ${CORE_SOURCE_FILES} ${CORE_HEADER_FILES} + ${CORE_SOURCE_FILES} ${CORE_HEADER_FILES} +) +target_include_directories( KGeoBagCore + PUBLIC $ $ ) target_link_libraries( KGeoBagCore - KGeoBagMath + PUBLIC + Kommon + KGeoBagMath ) +if( KGeoBag_ENABLE_DEBUG ) + target_compile_definitions( KGeoBagCore PUBLIC KGeoBag_ENABLE_DEBUG ) +endif( KGeoBag_ENABLE_DEBUG ) + +if( KGeoBag_USE_GSL ) + target_compile_definitions( KGeoBagCore PUBLIC KGeoBag_USE_GSL ) +endif( KGeoBag_USE_GSL ) + +if( KGeoBag_USE_BOOST ) + target_compile_definitions( KGeoBagCore PUBLIC KGeoBag_USE_BOOST ) +endif() + # install kasper_install_headers( ${CORE_HEADER_FILES} ) kasper_install_libraries( KGeoBagCore ) diff --git a/KGeoBag/Source/Core/Source/KGSpace.cc b/KGeoBag/Source/Core/Source/KGSpace.cc index e62bbdc07..3142040f2 100644 --- a/KGeoBag/Source/Core/Source/KGSpace.cc +++ b/KGeoBag/Source/Core/Source/KGSpace.cc @@ -417,7 +417,7 @@ void KGSpace::Volume(const std::shared_ptr& aVolume) tBoundary->SetTags((*tAreaIt)->GetTags()); const std::shared_ptr tArea = std::dynamic_pointer_cast(*tAreaIt); if (tArea == nullptr){ - coremsg(eWarning)<< "failed to cast KGBoundary <"<< (*tAreaIt)->GetName() << "> to KGArea! Certain features (like calculating the distance to this surface) might not be available." <GetName() << "/"<< (*tAreaIt)->GetName() << "> to KGArea! Certain features (like calculating the distance to this surface) might not be available." <Area(tArea); AddBoundary(tBoundary); diff --git a/KGeoBag/Source/Extensions/Appearance/CMakeLists.txt b/KGeoBag/Source/Extensions/Appearance/CMakeLists.txt index e377591fb..dddd679c2 100644 --- a/KGeoBag/Source/Extensions/Appearance/CMakeLists.txt +++ b/KGeoBag/Source/Extensions/Appearance/CMakeLists.txt @@ -2,30 +2,28 @@ set( APPEARANCE_HEADER_FILES Include/KGRGBColor.hh Include/KGRGBAColor.hh - Include/KGAppearance.hh + Include/KGAppearance.hh ) # sources set( APPEARANCE_SOURCE_FILES Source/KGRGBColor.cc Source/KGRGBAColor.cc - Source/KGAppearance.cc -) - -# internal -kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Include + Source/KGAppearance.cc ) # target -add_library( KGeoBagAppearance SHARED ${APPEARANCE_SOURCE_FILES} ${APPEARANCE_HEADER_FILES} ) +add_library( KGeoBagAppearance SHARED + ${APPEARANCE_SOURCE_FILES} ${APPEARANCE_HEADER_FILES} +) +target_include_directories( KGeoBagAppearance + PUBLIC $ $ +) target_link_libraries( KGeoBagAppearance - KGeoBagCore - ${Kommon_LIBRARIES} + PUBLIC + KGeoBagCore ) # install kasper_install_headers( ${APPEARANCE_HEADER_FILES} ) kasper_install_libraries( KGeoBagAppearance ) - - diff --git a/KGeoBag/Source/Extensions/AxialMesh/CMakeLists.txt b/KGeoBag/Source/Extensions/AxialMesh/CMakeLists.txt index 58078d1a2..3ee3fffd3 100644 --- a/KGeoBag/Source/Extensions/AxialMesh/CMakeLists.txt +++ b/KGeoBag/Source/Extensions/AxialMesh/CMakeLists.txt @@ -1,69 +1,69 @@ # headers set( AXIALMESH_HEADER_FILES - Include/KGAxialMeshMessage.hh - + Include/KGAxialMeshMessage.hh + Include/KGAxialMeshElement.hh Include/KGAxialMeshLoop.hh Include/KGAxialMeshRing.hh - + Include/KGAxialMesh.hh Include/KGAxialMesherBase.hh Include/KGAxialMesher.hh - + Simple/Include/KGSimpleAxialMesher.hh Simple/Include/KGRotatedLineSegmentSurfaceAxialMesher.hh - Simple/Include/KGRotatedArcSegmentSurfaceAxialMesher.hh - Simple/Include/KGRotatedPolyLineSurfaceAxialMesher.hh - Simple/Include/KGRotatedCircleSurfaceAxialMesher.hh - Simple/Include/KGRotatedPolyLoopSurfaceAxialMesher.hh - Simple/Include/KGRotatedLineSegmentSpaceAxialMesher.hh - Simple/Include/KGRotatedArcSegmentSpaceAxialMesher.hh - Simple/Include/KGRotatedPolyLineSpaceAxialMesher.hh - Simple/Include/KGRotatedCircleSpaceAxialMesher.hh - Simple/Include/KGRotatedPolyLoopSpaceAxialMesher.hh + Simple/Include/KGRotatedArcSegmentSurfaceAxialMesher.hh + Simple/Include/KGRotatedPolyLineSurfaceAxialMesher.hh + Simple/Include/KGRotatedCircleSurfaceAxialMesher.hh + Simple/Include/KGRotatedPolyLoopSurfaceAxialMesher.hh + Simple/Include/KGRotatedLineSegmentSpaceAxialMesher.hh + Simple/Include/KGRotatedArcSegmentSpaceAxialMesher.hh + Simple/Include/KGRotatedPolyLineSpaceAxialMesher.hh + Simple/Include/KGRotatedCircleSpaceAxialMesher.hh + Simple/Include/KGRotatedPolyLoopSpaceAxialMesher.hh ) # sources set( AXIALMESH_SOURCE_FILES - Source/KGAxialMeshMessage.cc - + Source/KGAxialMeshMessage.cc + Source/KGAxialMeshElement.cc Source/KGAxialMeshLoop.cc Source/KGAxialMeshRing.cc - + Source/KGAxialMesh.cc Source/KGAxialMesherBase.cc Source/KGAxialMesher.cc - + Simple/Source/KGSimpleAxialMesher.cc - Simple/Source/KGRotatedLineSegmentSurfaceAxialMesher.cc - Simple/Source/KGRotatedArcSegmentSurfaceAxialMesher.cc - Simple/Source/KGRotatedPolyLineSurfaceAxialMesher.cc - Simple/Source/KGRotatedCircleSurfaceAxialMesher.cc - Simple/Source/KGRotatedPolyLoopSurfaceAxialMesher.cc - Simple/Source/KGRotatedLineSegmentSpaceAxialMesher.cc - Simple/Source/KGRotatedArcSegmentSpaceAxialMesher.cc - Simple/Source/KGRotatedPolyLineSpaceAxialMesher.cc - Simple/Source/KGRotatedCircleSpaceAxialMesher.cc - Simple/Source/KGRotatedPolyLoopSpaceAxialMesher.cc + Simple/Source/KGRotatedLineSegmentSurfaceAxialMesher.cc + Simple/Source/KGRotatedArcSegmentSurfaceAxialMesher.cc + Simple/Source/KGRotatedPolyLineSurfaceAxialMesher.cc + Simple/Source/KGRotatedCircleSurfaceAxialMesher.cc + Simple/Source/KGRotatedPolyLoopSurfaceAxialMesher.cc + Simple/Source/KGRotatedLineSegmentSpaceAxialMesher.cc + Simple/Source/KGRotatedArcSegmentSpaceAxialMesher.cc + Simple/Source/KGRotatedPolyLineSpaceAxialMesher.cc + Simple/Source/KGRotatedCircleSpaceAxialMesher.cc + Simple/Source/KGRotatedPolyLoopSpaceAxialMesher.cc ) -# internal -kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Simple/Include +# target +add_library( KGeoBagAxialMesh SHARED + ${AXIALMESH_SOURCE_FILES} ${AXIALMESH_HEADER_FILES}) +target_include_directories( KGeoBagAxialMesh + PUBLIC + $ + $ + $ ) -# target -add_library( KGeoBagAxialMesh SHARED ${AXIALMESH_SOURCE_FILES} ${AXIALMESH_HEADER_FILES} ) target_link_libraries( KGeoBagAxialMesh - ${Kommon_LIBRARIES} - KGeoBagCore - KGeoBagShapes + PUBLIC + KGeoBagShapes + KGeoBagMathSpaceTree ) # install kasper_install_headers( ${AXIALMESH_HEADER_FILES} ) kasper_install_libraries( KGeoBagAxialMesh ) - - diff --git a/KGeoBag/Source/Extensions/Deformation/CMakeLists.txt b/KGeoBag/Source/Extensions/Deformation/CMakeLists.txt index b4d47873f..84142563f 100644 --- a/KGeoBag/Source/Extensions/Deformation/CMakeLists.txt +++ b/KGeoBag/Source/Extensions/Deformation/CMakeLists.txt @@ -15,25 +15,17 @@ set( DEFORMATION_SOURCE_FILES Source/KGMeshDeformer.cc ) -# internal -kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Include -) - # target add_library( KGeoBagDeformation SHARED - ${DEFORMATION_SOURCE_FILES} ${DEFORMATION_HEADER_FILES} -) + ${DEFORMATION_SOURCE_FILES} ${DEFORMATION_HEADER_FILES}) +target_include_directories( KGeoBagDeformation + PUBLIC $ $) target_link_libraries( KGeoBagDeformation - KGeoBagMath - KGeoBagCore - KGeoBagShapes - KGeoBagMesh - ${Kommon_LIBRARIES} + PUBLIC + KGeoBagShapes + KGeoBagMesh ) # install kasper_install_headers( ${DEFORMATION_HEADER_FILES} ) kasper_install_libraries( KGeoBagDeformation ) - - diff --git a/KGeoBag/Source/Extensions/DiscreteRotationalMesh/CMakeLists.txt b/KGeoBag/Source/Extensions/DiscreteRotationalMesh/CMakeLists.txt index c0dbb3029..bed7499da 100644 --- a/KGeoBag/Source/Extensions/DiscreteRotationalMesh/CMakeLists.txt +++ b/KGeoBag/Source/Extensions/DiscreteRotationalMesh/CMakeLists.txt @@ -1,44 +1,43 @@ # headers set( DISCRETEROTATIONALMESH_HEADER_FILES - Include/KGDiscreteRotationalAreaMesher.hh - Include/KGDiscreteRotationalMeshMessage.hh - Include/KGDiscreteRotationalMeshElement.hh - Include/KGDiscreteRotationalMesh.hh - Include/KGDiscreteRotationalMesherBase.hh - Include/KGDiscreteRotationalMesher.hh - - Complex/Include/KGConicalWireArrayDiscreteRotationalMesher.hh + Include/KGDiscreteRotationalAreaMesher.hh + Include/KGDiscreteRotationalMeshMessage.hh + Include/KGDiscreteRotationalMeshElement.hh + Include/KGDiscreteRotationalMesh.hh + Include/KGDiscreteRotationalMesherBase.hh + Include/KGDiscreteRotationalMesher.hh + + Complex/Include/KGConicalWireArrayDiscreteRotationalMesher.hh ) # sources set( DISCRETEROTATIONALMESH_SOURCE_FILES - Source/KGDiscreteRotationalMeshMessage.cc - Source/KGDiscreteRotationalMeshElement.cc - Source/KGDiscreteRotationalMesh.cc - Source/KGDiscreteRotationalMesherBase.cc - Source/KGDiscreteRotationalMesher.cc - - Complex/Source/KGConicalWireArrayDiscreteRotationalMesher.cc -) + Source/KGDiscreteRotationalMeshMessage.cc + Source/KGDiscreteRotationalMeshElement.cc + Source/KGDiscreteRotationalMesh.cc + Source/KGDiscreteRotationalMesherBase.cc + Source/KGDiscreteRotationalMesher.cc -# internal -kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Complex/Include + Complex/Source/KGConicalWireArrayDiscreteRotationalMesher.cc ) # target -add_library( KGeoBagDiscreteRotationalMesh SHARED ${DISCRETEROTATIONALMESH_SOURCE_FILES} ${DISCRETEROTATIONALMESH_HEADER_FILES} ) +add_library( KGeoBagDiscreteRotationalMesh SHARED + ${DISCRETEROTATIONALMESH_SOURCE_FILES} ${DISCRETEROTATIONALMESH_HEADER_FILES}) +target_include_directories( KGeoBagDiscreteRotationalMesh + PUBLIC + $ + $ + $ +) target_link_libraries( KGeoBagDiscreteRotationalMesh - ${Kommon_LIBRARIES} - KGeoBagCore - KGeoBagShapes - KGeoBagMesh - KGeoBagAxialMesh + PUBLIC + KGeoBagShapes + KGeoBagMathSpaceTree + KGeoBagMesh + KGeoBagAxialMesh ) # install kasper_install_headers( ${DISCRETEROTATIONALMESH_HEADER_FILES} ) kasper_install_libraries( KGeoBagDiscreteRotationalMesh ) - - diff --git a/KGeoBag/Source/Extensions/Intersection/CMakeLists.txt b/KGeoBag/Source/Extensions/Intersection/CMakeLists.txt index ec7bafeeb..8834e893a 100644 --- a/KGeoBag/Source/Extensions/Intersection/CMakeLists.txt +++ b/KGeoBag/Source/Extensions/Intersection/CMakeLists.txt @@ -12,19 +12,16 @@ set( INTERSECTION_SOURCE_FILES Source/KGRotatedSurfaceIntersector.cc ) -# internal -kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Include -) - # target add_library( KGeoBagIntersection SHARED - ${INTERSECTION_SOURCE_FILES} ${INTERSECTION_HEADER_FILES} + ${INTERSECTION_SOURCE_FILES} ${INTERSECTION_HEADER_FILES} +) +target_include_directories( KGeoBagIntersection + PUBLIC $ $ ) target_link_libraries( KGeoBagIntersection - KGeoBagCore - KGeoBagShapes - ${Kommon_LIBRARIES} + PUBLIC + KGeoBagShapes ) # install diff --git a/KGeoBag/Source/Extensions/Mesh/CMakeLists.txt b/KGeoBag/Source/Extensions/Mesh/CMakeLists.txt index 813e544f4..22b89a889 100644 --- a/KGeoBag/Source/Extensions/Mesh/CMakeLists.txt +++ b/KGeoBag/Source/Extensions/Mesh/CMakeLists.txt @@ -1,6 +1,6 @@ # headers set( MESH_HEADER_FILES - Include/KGMeshMessage.hh + Include/KGMeshMessage.hh Include/KGMeshElement.hh Include/KGMeshRectangle.hh @@ -11,6 +11,9 @@ set( MESH_HEADER_FILES Include/KGMesherBase.hh Include/KGMesher.hh + External/Include/KGStlFileSurfaceMesher.hh + External/Include/KGStlFileSpaceMesher.hh + Complex/Include/KGComplexMesher.hh Complex/Include/KGBoxMesher.hh Complex/Include/KGCylinderMesher.hh @@ -53,24 +56,24 @@ set( MESH_HEADER_FILES Simple/Include/KGExtrudedCircleSpaceMesher.hh Simple/Include/KGExtrudedPolyLoopSpaceMesher.hh - Navigation/Include/KGNavigableMeshElement.hh - Navigation/Include/KGMeshNavigationNode.hh - Navigation/Include/KGMeshElementCollector.hh - Navigation/Include/KGNavigableMeshElementContainer.hh - Navigation/Include/KGInsertionCondition.hh - Navigation/Include/KGNavigableMeshElementSorter.hh - Navigation/Include/KGSubdivisionCondition.hh - Navigation/Include/KGNavigableMeshTree.hh - Navigation/Include/KGNavigableMeshTreeBuilder.hh - Navigation/Include/KGNavigableMeshTreeInformationExtractor.hh - Navigation/Include/KGNavigableMeshFirstIntersectionFinder.hh - Navigation/Include/KGNavigableMeshIntersectionFinder.hh - Navigation/Include/KGNavigableMeshProximityCheck.hh + Navigation/Include/KGNavigableMeshElement.hh + Navigation/Include/KGMeshNavigationNode.hh + Navigation/Include/KGMeshElementCollector.hh + Navigation/Include/KGNavigableMeshElementContainer.hh + Navigation/Include/KGInsertionCondition.hh + Navigation/Include/KGNavigableMeshElementSorter.hh + Navigation/Include/KGSubdivisionCondition.hh + Navigation/Include/KGNavigableMeshTree.hh + Navigation/Include/KGNavigableMeshTreeBuilder.hh + Navigation/Include/KGNavigableMeshTreeInformationExtractor.hh + Navigation/Include/KGNavigableMeshFirstIntersectionFinder.hh + Navigation/Include/KGNavigableMeshIntersectionFinder.hh + Navigation/Include/KGNavigableMeshProximityCheck.hh ) # sources set( MESH_SOURCE_FILES - Source/KGMeshMessage.cc + Source/KGMeshMessage.cc Source/KGMeshElement.cc Source/KGMeshRectangle.cc @@ -81,6 +84,9 @@ set( MESH_SOURCE_FILES Source/KGMesherBase.cc Source/KGMesher.cc + External/Source/KGStlFileSurfaceMesher.cc + External/Source/KGStlFileSpaceMesher.cc + Complex/Source/KGComplexMesher.cc Complex/Source/KGBoxMesher.cc Complex/Source/KGCylinderMesher.cc @@ -123,37 +129,35 @@ set( MESH_SOURCE_FILES Simple/Source/KGExtrudedCircleSpaceMesher.cc Simple/Source/KGExtrudedPolyLoopSpaceMesher.cc - Navigation/Source/KGNavigableMeshElement.cc - Navigation/Source/KGMeshElementCollector.cc - Navigation/Source/KGNavigableMeshElementContainer.cc - Navigation/Source/KGInsertionCondition.cc - Navigation/Source/KGNavigableMeshElementSorter.cc - Navigation/Source/KGSubdivisionCondition.cc - Navigation/Source/KGNavigableMeshTreeBuilder.cc - Navigation/Source/KGNavigableMeshFirstIntersectionFinder.cc - Navigation/Source/KGNavigableMeshIntersectionFinder.cc - Navigation/Source/KGNavigableMeshProximityCheck.cc -) - -# internal -kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Complex/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Simple/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Navigation/Include + Navigation/Source/KGNavigableMeshElement.cc + Navigation/Source/KGMeshElementCollector.cc + Navigation/Source/KGNavigableMeshElementContainer.cc + Navigation/Source/KGInsertionCondition.cc + Navigation/Source/KGNavigableMeshElementSorter.cc + Navigation/Source/KGSubdivisionCondition.cc + Navigation/Source/KGNavigableMeshTreeBuilder.cc + Navigation/Source/KGNavigableMeshFirstIntersectionFinder.cc + Navigation/Source/KGNavigableMeshIntersectionFinder.cc + Navigation/Source/KGNavigableMeshProximityCheck.cc ) - # target -add_library( KGeoBagMesh SHARED ${MESH_SOURCE_FILES} ${MESH_HEADER_FILES} ) +add_library( KGeoBagMesh SHARED + ${MESH_SOURCE_FILES} ${MESH_HEADER_FILES} +) +target_include_directories( KGeoBagMesh + PUBLIC + $ + $ + $ + $ + $ + $ +) target_link_libraries( KGeoBagMesh - KGeoBagCore - KGeoBagShapes - KGeoBag2DUtility - KGeoBagMath - KGeoBagMathLinearAlgebra - KGeoBagMathSpaceTree - ${Kommon_LIBRARIES} + PUBLIC + KGeoBagShapes + KGeoBagMathSpaceTree ) # install diff --git a/KGeoBag/Source/Extensions/Mesh/Complex/Include/KGComplexMesher.hh b/KGeoBag/Source/Extensions/Mesh/Complex/Include/KGComplexMesher.hh index 178064de3..22237bdf6 100644 --- a/KGeoBag/Source/Extensions/Mesh/Complex/Include/KGComplexMesher.hh +++ b/KGeoBag/Source/Extensions/Mesh/Complex/Include/KGComplexMesher.hh @@ -24,7 +24,11 @@ class KGComplexMesher : virtual public KGMesherBase static void DiscretizeInterval(double interval, int nSegments, double power, std::vector& segments); protected: - void AddElement(KGMeshElement* e); + //void AddElement(KGMeshElement* e); + + template + void AddElement(MeshType* e, bool checkNormals = true); + void RefineAndAddElement(KGMeshRectangle* rectangle, int nElements_A, double power_A, int nElements_B, double power_B); void RefineAndAddElement(KGMeshTriangle* triangle, int nElements, double power); diff --git a/KGeoBag/Source/Extensions/Mesh/Complex/Include/KGExtrudedSurfaceMesher.hh b/KGeoBag/Source/Extensions/Mesh/Complex/Include/KGExtrudedSurfaceMesher.hh index 3c2470098..84ddf7478 100644 --- a/KGeoBag/Source/Extensions/Mesh/Complex/Include/KGExtrudedSurfaceMesher.hh +++ b/KGeoBag/Source/Extensions/Mesh/Complex/Include/KGExtrudedSurfaceMesher.hh @@ -25,7 +25,7 @@ class KGExtrudedSurfaceMesher : virtual public KGComplexMesher, public KGExtrude void DiscretizeSegment(const KGExtrudedObject::Arc* arc, const unsigned int nDisc, std::vector>& coords, unsigned int& counter); void DiscretizeEnclosedEnds(std::vector>& iCoords, std::vector>& oCoords, - unsigned int nDisc); + unsigned int nDisc, double mergeDist = 0. /*1.E-4*/); void DiscretizeLoopEnds(); virtual void ModifyInnerSegment(int, std::vector>&) {} diff --git a/KGeoBag/Source/Extensions/Mesh/Complex/Source/KGComplexMesher.cc b/KGeoBag/Source/Extensions/Mesh/Complex/Source/KGComplexMesher.cc index e12f1d83c..5cff2a645 100644 --- a/KGeoBag/Source/Extensions/Mesh/Complex/Source/KGComplexMesher.cc +++ b/KGeoBag/Source/Extensions/Mesh/Complex/Source/KGComplexMesher.cc @@ -11,7 +11,15 @@ namespace KGeoBag KGComplexMesher::KGComplexMesher() = default; KGComplexMesher::~KGComplexMesher() = default; -void KGComplexMesher::AddElement(KGMeshElement* e) +template<> +void KGComplexMesher::AddElement(KGMeshWire* e, bool /*checkNormals*/) +{ + fCurrentElements->push_back(e); + return; +} + +template<> +void KGComplexMesher::AddElement(KGMeshTriangle* t, bool checkNormals) { //J.B. 4/1/2015 //need to check that the normal vector for this mesh triangle points @@ -19,77 +27,66 @@ void KGComplexMesher::AddElement(KGMeshElement* e) //surface that we are meshing, this condition is important for //the boundary element solver when Neumann boundary conditions are encountered - //figure out if we have a triangle, rectangle, or wire element - //TODO figure out a way to get rid of these dynamics casts - KGMeshTriangle* t = nullptr; - t = dynamic_cast(e); - - KGMeshRectangle* r = nullptr; - r = dynamic_cast(e); - - bool have_triangle = false; - if (t != nullptr) { - have_triangle = true; - }; - - bool have_rectangle = false; - if (r != nullptr) { - have_rectangle = true; - }; - - if (have_triangle) { - //get the nearest normal to the centroid - if (fCurrentSurface != nullptr) { - KThreeVector p0 = t->GetP0(); - KThreeVector p1 = t->GetP1(); - KThreeVector p2 = t->GetP2(); - - //compute the centroid - KThreeVector centroid = (p0 + p1 + p2) / 3.0; - KThreeVector surface_normal = fCurrentSurface->Normal(centroid); - - //compute the normal vector of mesh triangle - KThreeVector triangle_normal = t->GetN3(); - //now determine if the triangle normal points in approximately same direction - //as the 'above' surface normal - if (triangle_normal.Dot(surface_normal) < -1e-9) { - //they point in opposite directions, so flip the ordering of the - //second and third points for this triangle - *t = KGMeshTriangle(p0, p2, p1); - } + //get the nearest normal to the centroid + if (fCurrentSurface != nullptr && checkNormals) { + const KThreeVector& p0 = t->GetP0(); + const KThreeVector& p1 = t->GetP1(); + const KThreeVector& p2 = t->GetP2(); + + //compute the centroid + KThreeVector centroid = (p0 + p1 + p2) / 3.0; + KThreeVector surface_normal = fCurrentSurface->Normal(centroid); + + //compute the normal vector of mesh triangle + KThreeVector triangle_normal = t->GetN3(); + //now determine if the triangle normal points in approximately same direction + //as the 'above' surface normal + if (triangle_normal.Dot(surface_normal) < -1e-9) { + //they point in opposite directions, so flip the ordering of the + //second and third points for this triangle + *t = KGMeshTriangle(p0, p2, p1); } } - if (have_rectangle) { - //get the nearest normal to the centroid - if (fCurrentSurface != nullptr) { - KThreeVector p0 = r->GetP0(); - KThreeVector p1 = r->GetP1(); - KThreeVector p2 = r->GetP2(); - KThreeVector p3 = r->GetP3(); - - //compute the centroid - KThreeVector centroid = (p0 + p1 + p2 + p3) / 4.0; - KThreeVector surface_normal = fCurrentSurface->Normal(centroid); - - //compute the normal vector of mesh triangle - KThreeVector rectangle_normal = r->GetN3(); - //now determine if the rectangle normal points in approximately same direction - //as the 'above' surface normal - if (rectangle_normal.Dot(surface_normal) < -1e-9) { - //they point in opposite directions, so flip the ordering of the - //side vectors for this rectangle - double a = r->GetA(); - double b = r->GetB(); - KThreeVector n1 = r->GetN1(); - KThreeVector n2 = r->GetN2(); - *r = KGMeshRectangle(b, a, p0, n2, n1); - } + fCurrentElements->push_back(t); +} + +template<> +void KGComplexMesher::AddElement(KGMeshRectangle* r, bool checkNormals) +{ + //J.B. 4/1/2015 + //need to check that the normal vector for this mesh triangle points + //in (approximately) the same direction as the nearest normal on the + //surface that we are meshing, this condition is important for + //the boundary element solver when Neumann boundary conditions are encountered + + //get the nearest normal to the centroid + if (fCurrentSurface != nullptr && checkNormals) { + const KThreeVector& p0 = r->GetP0(); + const KThreeVector& p1 = r->GetP1(); + const KThreeVector& p2 = r->GetP2(); + const KThreeVector& p3 = r->GetP3(); + + //compute the centroid + KThreeVector centroid = (p0 + p1 + p2 + p3) / 4.0; + KThreeVector surface_normal = fCurrentSurface->Normal(centroid); + + //compute the normal vector of mesh triangle + KThreeVector rectangle_normal = r->GetN3(); + //now determine if the rectangle normal points in approximately same direction + //as the 'above' surface normal + if (rectangle_normal.Dot(surface_normal) < -1e-9) { + //they point in opposite directions, so flip the ordering of the + //side vectors for this rectangle + double a = r->GetA(); + double b = r->GetB(); + KThreeVector n1 = r->GetN1(); + KThreeVector n2 = r->GetN2(); + *r = KGMeshRectangle(b, a, p0, n2, n1); } } - fCurrentElements->push_back(e); - return; + fCurrentElements->push_back(r); } void KGComplexMesher::DiscretizeInterval(double interval, int nSegments, double power, std::vector& segments) diff --git a/KGeoBag/Source/Extensions/Mesh/Complex/Source/KGExtrudedSurfaceMesher.cc b/KGeoBag/Source/Extensions/Mesh/Complex/Source/KGExtrudedSurfaceMesher.cc index 8aecb3d59..10a92df37 100644 --- a/KGeoBag/Source/Extensions/Mesh/Complex/Source/KGExtrudedSurfaceMesher.cc +++ b/KGeoBag/Source/Extensions/Mesh/Complex/Source/KGExtrudedSurfaceMesher.cc @@ -5,7 +5,7 @@ #include -#define MERGE_DIST 1.e-4 +//#define MERGE_DIST 1.e-4 namespace KGeoBag { @@ -20,6 +20,8 @@ void KGExtrudedSurfaceMesher::Discretize(KGExtrudedObject* object) { fExtrudedObject = object; + bool refineMesh = fExtrudedObject->RefineMesh(); + std::vector nInnerCoords(fExtrudedObject->GetNInnerSegments(), 0); std::vector nOuterCoords(fExtrudedObject->GetNOuterSegments(), 0); @@ -49,7 +51,7 @@ void KGExtrudedSurfaceMesher::Discretize(KGExtrudedObject* object) // First, we start with the outer segments // assign the segments a discretization according to their relative length - int nAssignedSegments = 0; + int nAssignedOuterSegments = 0; for (unsigned int i = 0; i < fExtrudedObject->GetNOuterSegments(); i++) { int nSegments; if (totalOuterLength > totalOuterLength) @@ -67,13 +69,16 @@ void KGExtrudedSurfaceMesher::Discretize(KGExtrudedObject* object) else if (nSegments < 4) nSegments = 4; outerDisc[i] = nSegments; - nAssignedSegments += nSegments; + nAssignedOuterSegments += nSegments; } + if (nAssignedOuterSegments != (int) nDisc) + discretizationHasChanged = true; + // next, we add the inner segments // assign the segments a discretization according to their relative length - nAssignedSegments = 0; + int nAssignedInnerSegments = 0; for (unsigned int i = 0; i < fExtrudedObject->GetNInnerSegments(); i++) { int nSegments; if (totalInnerLength > totalOuterLength) @@ -100,14 +105,16 @@ void KGExtrudedSurfaceMesher::Discretize(KGExtrudedObject* object) } innerDisc[i] = nSegments; - nAssignedSegments += nSegments; + nAssignedInnerSegments += nSegments; } - if (nAssignedSegments != (int) nDisc) + if (nAssignedInnerSegments != (int) nDisc) discretizationHasChanged = true; - if (nAssignedSegments != (int) nDisc) - discretizationHasChanged = true; + if (refineMesh && (nAssignedOuterSegments != nAssignedInnerSegments)) { + nDisc += 1; + continue; + } discretizationIsOk = true; @@ -161,7 +168,7 @@ void KGExtrudedSurfaceMesher::Discretize(KGExtrudedObject* object) if (fIsModifiable) ModifySurface(innerCoords, outerCoords, nInnerCoords, nOuterCoords); - DiscretizeEnclosedEnds(innerCoords, outerCoords, nDisc); + DiscretizeEnclosedEnds(innerCoords, outerCoords, nDisc, fExtrudedObject->MeshMergeDistance()); if (!(fExtrudedObject->ClosedLoops())) { DiscretizeLoopEnds(); @@ -227,7 +234,7 @@ void KGExtrudedSurfaceMesher::DiscretizeSegment(const KGExtrudedObject::Line* li nDisc, fExtrudedObject->GetDiscretizationPower(), nDisc, - fExtrudedObject->GetDiscretizationPower()); + fExtrudedObject->GetExtrudedMeshPower()); } //____________________________________________________________________________ @@ -281,7 +288,7 @@ void KGExtrudedSurfaceMesher::DiscretizeSegment(const KGExtrudedObject::Arc* arc 1, fExtrudedObject->GetDiscretizationPower(), z_len / xy_len, - fExtrudedObject->GetDiscretizationPower()); + fExtrudedObject->GetExtrudedMeshPower()); } std::vector xy(2); @@ -295,7 +302,8 @@ void KGExtrudedSurfaceMesher::DiscretizeSegment(const KGExtrudedObject::Arc* arc //____________________________________________________________________________ void KGExtrudedSurfaceMesher::DiscretizeEnclosedEnds(std::vector>& iCoords, - std::vector>& oCoords, unsigned int nDisc) + std::vector>& oCoords, unsigned int nDisc, + double mergeDist) { // For surfaces with closed ends, this method constructs the end caps. @@ -377,7 +385,7 @@ void KGExtrudedSurfaceMesher::DiscretizeEnclosedEnds(std::vector MERGE_DIST) + if (dist > mergeDist) continue; int pointsAreOnALine = 0; // 0 = false; 1 = below; 2 = above; 3 = both; @@ -437,7 +445,7 @@ void KGExtrudedSurfaceMesher::DiscretizeEnclosedEnds(std::vector MERGE_DIST) + if (dist > mergeDist) continue; int pointsAreOnALine = 0; // 0 = false; 1 = below; 2 = above; 3 = both; @@ -487,20 +495,6 @@ void KGExtrudedSurfaceMesher::DiscretizeEnclosedEnds(std::vectorClosedLoops()) - if (true) { - if (fExtrudedObject->IsBackwards()) { - std::sort(augmentedInnerCoords.rbegin(), augmentedInnerCoords.rend(), KGExtrudedObject::CompareTheta); - std::sort(augmentedOuterCoords.rbegin(), augmentedOuterCoords.rend(), KGExtrudedObject::CompareTheta); - } - else { - std::sort(augmentedInnerCoords.begin(), augmentedInnerCoords.end(), KGExtrudedObject::CompareTheta); - std::sort(augmentedOuterCoords.begin(), augmentedOuterCoords.end(), KGExtrudedObject::CompareTheta); - } - } - ///////////////////////// /* // now we try to merge points (simplified algorithm) @@ -516,7 +510,7 @@ void KGExtrudedSurfaceMesher::DiscretizeEnclosedEnds(std::vectorClosedLoops()) + if (true) { + if (fExtrudedObject->IsBackwards()) { + std::sort(augmentedInnerCoords.rbegin(), augmentedInnerCoords.rend(), KGExtrudedObject::CompareTheta); + std::sort(augmentedOuterCoords.rbegin(), augmentedOuterCoords.rend(), KGExtrudedObject::CompareTheta); + } + else { + std::sort(augmentedInnerCoords.begin(), augmentedInnerCoords.end(), KGExtrudedObject::CompareTheta); + std::sort(augmentedOuterCoords.begin(), augmentedOuterCoords.end(), KGExtrudedObject::CompareTheta); + } + } + iCoords.clear(); oCoords.clear(); diff --git a/KGeoBag/Source/Extensions/Mesh/External/Include/KGStlFileSpaceMesher.hh b/KGeoBag/Source/Extensions/Mesh/External/Include/KGStlFileSpaceMesher.hh new file mode 100644 index 000000000..6892764a3 --- /dev/null +++ b/KGeoBag/Source/Extensions/Mesh/External/Include/KGStlFileSpaceMesher.hh @@ -0,0 +1,31 @@ +/** + * @file KGStlFileSpaceMesher.hh + * @author Jan Behrens + * @date 2021-07-02 + */ + +#ifndef KGeoBag_KGStlFileSpaceMesher_hh_ +#define KGeoBag_KGStlFileSpaceMesher_hh_ + +#include "KGStlFileSpace.hh" +#include "KGComplexMesher.hh" + +namespace KGeoBag +{ + +class KGStlFileSpaceMesher : virtual public KGComplexMesher, public KGStlFileSpace::Visitor +{ + public: + using KGMesherBase::VisitExtendedSpace; + + public: + KGStlFileSpaceMesher() = default; + ~KGStlFileSpaceMesher() override = default; + + protected: + void VisitWrappedSpace(KGStlFileSpace* stlSpace) override; +}; + +} // namespace KGeoBag + +#endif /* KGBEAMSpaceMESHER_HH_ */ diff --git a/KGeoBag/Source/Extensions/Mesh/External/Include/KGStlFileSurfaceMesher.hh b/KGeoBag/Source/Extensions/Mesh/External/Include/KGStlFileSurfaceMesher.hh new file mode 100644 index 000000000..07dac35a2 --- /dev/null +++ b/KGeoBag/Source/Extensions/Mesh/External/Include/KGStlFileSurfaceMesher.hh @@ -0,0 +1,32 @@ +/** + * @file KGStlFileSurfaceMesher.hh + * @author Jan Behrens + * @date 2021-07-02 + */ + +#ifndef KGeoBag_KGStlFileSurfaceMesher_hh_ +#define KGeoBag_KGStlFileSurfaceMesher_hh_ + +#include "KGStlFileSurface.hh" +#include "KGComplexMesher.hh" + +namespace KGeoBag +{ + +class KGStlFileSurfaceMesher : virtual public KGComplexMesher, public KGStlFileSurface::Visitor +{ + public: + using KGMesherBase::VisitExtendedSurface; + + public: + KGStlFileSurfaceMesher() = default; + ~KGStlFileSurfaceMesher() override = default; + + protected: + void VisitWrappedSurface(KGStlFileSurface* stlSurface) override; + +}; + +} // namespace KGeoBag + +#endif /* KGBEAMSURFACEMESHER_HH_ */ diff --git a/KGeoBag/Source/Extensions/Mesh/External/Source/KGStlFileSpaceMesher.cc b/KGeoBag/Source/Extensions/Mesh/External/Source/KGStlFileSpaceMesher.cc new file mode 100644 index 000000000..96e96bca7 --- /dev/null +++ b/KGeoBag/Source/Extensions/Mesh/External/Source/KGStlFileSpaceMesher.cc @@ -0,0 +1,30 @@ +/** + * @file KGStlFileSpaceMesher.cc + * @author Jan Behrens + * @date 2021-07-02 + */ + +#include "KGStlFileSpaceMesher.hh" + +using namespace KGeoBag; + +void KGStlFileSpaceMesher::VisitWrappedSpace(KGStlFileSpace* stlSpace) +{ + auto object = stlSpace->GetObject(); + + auto nElements = object->GetNumSolidElements(); + coremsg(eInfo) << "Adding <" << nElements << "> solid surface elements to the mesh" << eom; + + fCurrentElements->reserve(fCurrentElements->size() + nElements); + + for (auto & solid : object->GetSolids()) { + for (auto & elem : solid) { + auto t = new KGMeshTriangle(elem); + + if (object->GetNDisc() < 2) + AddElement(t, false); + else + RefineAndAddElement(t, object->GetNDisc(), 1); + } + } +} diff --git a/KGeoBag/Source/Extensions/Mesh/External/Source/KGStlFileSurfaceMesher.cc b/KGeoBag/Source/Extensions/Mesh/External/Source/KGStlFileSurfaceMesher.cc new file mode 100644 index 000000000..38e38bad9 --- /dev/null +++ b/KGeoBag/Source/Extensions/Mesh/External/Source/KGStlFileSurfaceMesher.cc @@ -0,0 +1,28 @@ +/** + * @file KGStlFileSurfaceMesher.cc + * @author Jan Behrens + * @date 2021-07-02 + */ + +#include "KGStlFileSurfaceMesher.hh" + +using namespace KGeoBag; + +void KGStlFileSurfaceMesher::VisitWrappedSurface(KGStlFileSurface* stlSurface) +{ + auto object = stlSurface->GetObject(); + + auto nElements = object->GetNumElements(); + coremsg(eInfo) << "Adding <" << nElements << "> surface elements to the mesh" << eom; + + fCurrentElements->reserve(fCurrentElements->size() + nElements); + + for (auto & elem : object->GetElements()) { + auto t = new KGMeshTriangle(elem); + + if (object->GetNDisc() < 2) + AddElement(t, false); + else + RefineAndAddElement(t, object->GetNDisc(), 1); + } +} diff --git a/KGeoBag/Source/Extensions/Mesh/Include/KGMeshRectangle.hh b/KGeoBag/Source/Extensions/Mesh/Include/KGMeshRectangle.hh index f1d619a22..fb90ad61e 100644 --- a/KGeoBag/Source/Extensions/Mesh/Include/KGMeshRectangle.hh +++ b/KGeoBag/Source/Extensions/Mesh/Include/KGMeshRectangle.hh @@ -2,6 +2,7 @@ #define KGMESHRECTANGLE_DEF #include "KGMeshElement.hh" +#include "KGRectangle.hh" #include "KThreeVector.hh" namespace KGeoBag @@ -13,6 +14,7 @@ class KGMeshRectangle : public KGMeshElement const KGeoBag::KThreeVector& n2); KGMeshRectangle(const KGeoBag::KThreeVector& p0, const KGeoBag::KThreeVector& p1, const KGeoBag::KThreeVector& /*p2*/, const KGeoBag::KThreeVector& p3); + KGMeshRectangle(const KGRectangle& t); KGMeshRectangle(const KGMeshRectangle& r); ~KGMeshRectangle() override; diff --git a/KGeoBag/Source/Extensions/Mesh/Include/KGMeshTriangle.hh b/KGeoBag/Source/Extensions/Mesh/Include/KGMeshTriangle.hh index 11983deeb..e26a2b11d 100644 --- a/KGeoBag/Source/Extensions/Mesh/Include/KGMeshTriangle.hh +++ b/KGeoBag/Source/Extensions/Mesh/Include/KGMeshTriangle.hh @@ -2,6 +2,7 @@ #define KGMESHTRIANGLE_DEF #include "KGMeshElement.hh" +#include "KGTriangle.hh" #include "KThreeVector.hh" namespace KGeoBag @@ -12,6 +13,7 @@ class KGMeshTriangle : public KGMeshElement KGMeshTriangle(const double& a, const double& b, const KGeoBag::KThreeVector& p0, const KGeoBag::KThreeVector& n1, const KGeoBag::KThreeVector& n2); KGMeshTriangle(const KGeoBag::KThreeVector& p0, const KGeoBag::KThreeVector& p1, const KGeoBag::KThreeVector& p2); + KGMeshTriangle(const KGTriangle& t); KGMeshTriangle(const KGMeshTriangle& t); ~KGMeshTriangle() override; @@ -24,10 +26,10 @@ class KGMeshTriangle : public KGMeshElement double Aspect() const override; void Transform(const KTransformation& transform) override; - double NearestDistance(const KGeoBag::KThreeVector& aPoint) const override; - KGeoBag::KThreeVector NearestPoint(const KGeoBag::KThreeVector& aPoint) const override; - KGeoBag::KThreeVector NearestNormal(const KGeoBag::KThreeVector& aPoint) const override; - bool NearestIntersection(const KGeoBag::KThreeVector& aStart, const KGeoBag::KThreeVector& anEnd, + virtual double NearestDistance(const KGeoBag::KThreeVector& aPoint) const override; + virtual KGeoBag::KThreeVector NearestPoint(const KGeoBag::KThreeVector& aPoint) const override; + virtual KGeoBag::KThreeVector NearestNormal(const KGeoBag::KThreeVector& aPoint) const override; + virtual bool NearestIntersection(const KGeoBag::KThreeVector& aStart, const KGeoBag::KThreeVector& anEnd, KGeoBag::KThreeVector& anIntersection) const override; KGPointCloud GetPointCloud() const override; @@ -109,18 +111,18 @@ class KGMeshTriangle : public KGMeshElement protected: static bool SameSide(const KGeoBag::KThreeVector& point, const KGeoBag::KThreeVector& A, - const KGeoBag::KThreeVector& B, const KGeoBag::KThreeVector& C); + const KGeoBag::KThreeVector& B, const KGeoBag::KThreeVector& C); static KGeoBag::KThreeVector NearestPointOnLineSegment(const KGeoBag::KThreeVector& a, - const KGeoBag::KThreeVector& b, - const KGeoBag::KThreeVector& point); - + const KGeoBag::KThreeVector& b, + const KGeoBag::KThreeVector& point); double fA; double fB; KGeoBag::KThreeVector fP0; KGeoBag::KThreeVector fN1; KGeoBag::KThreeVector fN2; }; + } // namespace KGeoBag #endif /* KGMESHTRIANGLE_DEF */ diff --git a/KGeoBag/Source/Extensions/Mesh/Include/KGMesher.hh b/KGeoBag/Source/Extensions/Mesh/Include/KGMesher.hh index da5cf2242..8c2a9836d 100644 --- a/KGeoBag/Source/Extensions/Mesh/Include/KGMesher.hh +++ b/KGeoBag/Source/Extensions/Mesh/Include/KGMesher.hh @@ -39,6 +39,8 @@ #include "KGShellLineSegmentSurfaceMesher.hh" #include "KGShellPolyLineSurfaceMesher.hh" #include "KGShellPolyLoopSurfaceMesher.hh" +#include "KGStlFileSurfaceMesher.hh" +#include "KGStlFileSpaceMesher.hh" namespace KGeoBag { @@ -59,6 +61,7 @@ class KGMesher : virtual public KGRotatedPolyLineSurfaceMesher, virtual public KGRotatedCircleSurfaceMesher, virtual public KGRotatedPolyLoopSurfaceMesher, + virtual public KGStlFileSurfaceMesher, virtual public KGLinearWireGridMesher, virtual public KGQuadraticWireGridMesher, virtual public KGCircleWireMesher, @@ -79,7 +82,8 @@ class KGMesher : virtual public KGRotatedCircleSpaceMesher, virtual public KGRotatedPolyLoopSpaceMesher, virtual public KGExtrudedCircleSpaceMesher, - virtual public KGExtrudedPolyLoopSpaceMesher + virtual public KGExtrudedPolyLoopSpaceMesher, + virtual public KGStlFileSpaceMesher { public: using KGMesherBase::VisitExtendedSpace; @@ -98,6 +102,7 @@ class KGMesher : using KGQuadraticWireGridMesher::VisitWrappedSurface; using KGRodSurfaceMesher::VisitWrappedSurface; using KGRotatedSurfaceMesher::VisitWrappedSurface; + using KGStlFileSurfaceMesher::VisitWrappedSurface; using KGExtrudedArcSegmentSurfaceMesher::VisitExtrudedPathSurface; using KGExtrudedCircleSpaceMesher::VisitExtrudedClosedPathSpace; @@ -123,6 +128,7 @@ class KGMesher : using KGShellLineSegmentSurfaceMesher::VisitShellPathSurface; using KGShellPolyLineSurfaceMesher::VisitShellPathSurface; using KGShellPolyLoopSurfaceMesher::VisitShellPathSurface; + using KGStlFileSpaceMesher::VisitWrappedSpace; public: KGMesher(); diff --git a/KGeoBag/Source/Extensions/Mesh/Source/KGMeshRectangle.cc b/KGeoBag/Source/Extensions/Mesh/Source/KGMeshRectangle.cc index fbd495f44..b734bfcea 100644 --- a/KGeoBag/Source/Extensions/Mesh/Source/KGMeshRectangle.cc +++ b/KGeoBag/Source/Extensions/Mesh/Source/KGMeshRectangle.cc @@ -28,6 +28,13 @@ KGMeshRectangle::KGMeshRectangle(const KThreeVector& p0, const KThreeVector& p1, fB = fN2.Magnitude(); fN2 = fN2.Unit(); } +KGMeshRectangle::KGMeshRectangle(const KGRectangle& r) : + fA(r.GetA()), + fB(r.GetB()), + fP0(r.GetP0()), + fN1(r.GetN1()), + fN2(r.GetN2()) +{} KGMeshRectangle::KGMeshRectangle(const KGMeshRectangle&) = default; KGMeshRectangle::~KGMeshRectangle() = default; diff --git a/KGeoBag/Source/Extensions/Mesh/Source/KGMeshTriangle.cc b/KGeoBag/Source/Extensions/Mesh/Source/KGMeshTriangle.cc index e371216a6..fa40493cb 100644 --- a/KGeoBag/Source/Extensions/Mesh/Source/KGMeshTriangle.cc +++ b/KGeoBag/Source/Extensions/Mesh/Source/KGMeshTriangle.cc @@ -9,13 +9,9 @@ namespace KGeoBag { -KGMeshTriangle::KGMeshTriangle(const double& fA, const double& fB, const KThreeVector& p0, const KThreeVector& n1, +KGMeshTriangle::KGMeshTriangle(const double& a, const double& b, const KThreeVector& p0, const KThreeVector& n1, const KThreeVector& n2) : - fA(fA), - fB(fB), - fP0(p0), - fN1(n1), - fN2(n2) + fA(a), fB(b), fP0(p0), fN1(n1), fN2(n2) {} KGMeshTriangle::KGMeshTriangle(const KThreeVector& p0, const KThreeVector& p1, const KThreeVector& p2) { @@ -27,6 +23,13 @@ KGMeshTriangle::KGMeshTriangle(const KThreeVector& p0, const KThreeVector& p1, c fB = fN2.Magnitude(); fN2 = fN2.Unit(); } +KGMeshTriangle::KGMeshTriangle(const KGTriangle& t) : + fA(t.GetA()), + fB(t.GetB()), + fP0(t.GetP0()), + fN1(t.GetN1()), + fN2(t.GetN2()) +{} KGMeshTriangle::KGMeshTriangle(const KGMeshTriangle&) = default; KGMeshTriangle::~KGMeshTriangle() = default; @@ -111,6 +114,34 @@ void KGMeshTriangle::Transform(const KTransformation& transform) transform.ApplyRotation(fN2); } +KGPointCloud KGMeshTriangle::GetPointCloud() const +{ + KGPointCloud point_cloud; + point_cloud.AddPoint(KGPoint(fP0)); + point_cloud.AddPoint(KGPoint(fP0 + fA * fN1)); + point_cloud.AddPoint(KGPoint(fP0 + fB * fN2)); + return point_cloud; +} + +void KGMeshTriangle::GetEdge(KThreeVector& start, KThreeVector& end, unsigned int index) const +{ + if (index == 0) { + start = fP0; + end = fP0 + fA * fN1; + return; + } + + if (index == 1) { + start = fP0 + fA * fN1; + end = fP0 + fB * fN2; + } + + if (index == 2) { + start = fP0 + fB * fN2; + end = fP0; + } +} + double KGMeshTriangle::NearestDistance(const KThreeVector& aPoint) const { KThreeVector nearest = NearestPoint(aPoint); @@ -244,34 +275,6 @@ bool KGMeshTriangle::NearestIntersection(const KThreeVector& aStart, const KThre return false; } -KGPointCloud KGMeshTriangle::GetPointCloud() const -{ - KGPointCloud point_cloud; - point_cloud.AddPoint(KGPoint(fP0)); - point_cloud.AddPoint(KGPoint(fP0 + fA * fN1)); - point_cloud.AddPoint(KGPoint(fP0 + fB * fN2)); - return point_cloud; -} - -void KGMeshTriangle::GetEdge(KThreeVector& start, KThreeVector& end, unsigned int index) const -{ - if (index == 0) { - start = fP0; - end = fP0 + fA * fN1; - return; - } - - if (index == 1) { - start = fP0 + fA * fN1; - end = fP0 + fB * fN2; - } - - if (index == 2) { - start = fP0 + fB * fN2; - end = fP0; - } -} - KThreeVector KGMeshTriangle::NearestPointOnLineSegment(const KThreeVector& a, const KThreeVector& b, const KThreeVector& point) diff --git a/KGeoBag/Source/Extensions/Metrics/CMakeLists.txt b/KGeoBag/Source/Extensions/Metrics/CMakeLists.txt index 12214556a..a18524186 100644 --- a/KGeoBag/Source/Extensions/Metrics/CMakeLists.txt +++ b/KGeoBag/Source/Extensions/Metrics/CMakeLists.txt @@ -10,21 +10,16 @@ set( METRICS_SOURCE_FILES Source/KGMetricsMessage.cc ) -# internal -kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Include -) - # target -add_library( KGeoBagMetrics SHARED ${METRICS_SOURCE_FILES} ${METRICS_HEADER_FILES} ) +add_library( KGeoBagMetrics SHARED + ${METRICS_SOURCE_FILES} ${METRICS_HEADER_FILES}) +target_include_directories( KGeoBagMetrics + PUBLIC $ $) target_link_libraries( KGeoBagMetrics - KGeoBagCore - KGeoBagShapes - ${Kommon_LIBRARIES} + PUBLIC + KGeoBagShapes ) # install kasper_install_headers( ${METRICS_HEADER_FILES} ) kasper_install_libraries( KGeoBagMetrics ) - - diff --git a/KGeoBag/Source/Extensions/Random/CMakeLists.txt b/KGeoBag/Source/Extensions/Random/CMakeLists.txt index 86412e6f4..da0bca1c0 100644 --- a/KGeoBag/Source/Extensions/Random/CMakeLists.txt +++ b/KGeoBag/Source/Extensions/Random/CMakeLists.txt @@ -39,22 +39,17 @@ set( RANDOM_SOURCE_FILES Source/KGGenericSurfaceRandom.cc ) -# internal -kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Include -) - # target -add_library( KGeoBagRandom SHARED ${RANDOM_SOURCE_FILES} ${RANDOM_HEADER_FILES} ) +add_library( KGeoBagRandom SHARED + ${RANDOM_SOURCE_FILES} ${RANDOM_HEADER_FILES}) +target_include_directories( KGeoBagRandom + PUBLIC $ $) target_link_libraries( KGeoBagRandom - KGeoBagCore - KGeoBagShapes - KGeoBagMetrics - ${Kommon_LIBRARIES} + PUBLIC + KGeoBagShapes + KGeoBagMetrics ) # install kasper_install_headers( ${RANDOM_HEADER_FILES} ) kasper_install_libraries( KGeoBagRandom ) - - diff --git a/KGeoBag/Source/Math/2DUtility/CMakeLists.txt b/KGeoBag/Source/Math/2DUtility/CMakeLists.txt index ca9651abf..da7dde37a 100644 --- a/KGeoBag/Source/Math/2DUtility/CMakeLists.txt +++ b/KGeoBag/Source/Math/2DUtility/CMakeLists.txt @@ -23,18 +23,14 @@ set( 2DUTILITY_SOURCE_FILES Source/KGInfinitePlane.cc ) -# internal -kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Include -) - # target -add_library( KGeoBag2DUtility SHARED ${2DUTILITY_SOURCE_FILES} ${2DUTILITY_HEADER_FILES}) - +add_library( KGeoBag2DUtility SHARED + ${2DUTILITY_SOURCE_FILES} ${2DUTILITY_HEADER_FILES}) +target_include_directories( KGeoBag2DUtility + PUBLIC $ $) target_link_libraries( KGeoBag2DUtility - KGeoBagCore - KGeoBagMath - ${Kommon_LIBRARIES} + PUBLIC + KGeoBagMath ) # install diff --git a/KGeoBag/Source/Math/CMakeLists.txt b/KGeoBag/Source/Math/CMakeLists.txt index b52797892..d2160ca4a 100644 --- a/KGeoBag/Source/Math/CMakeLists.txt +++ b/KGeoBag/Source/Math/CMakeLists.txt @@ -39,18 +39,14 @@ set( MATH_SOURCE_FILES Source/KGMathMessage.cc ) -# internal -kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Include -) - # target add_library( KGeoBagMath SHARED - ${MATH_SOURCE_FILES} ${MATH_HEADER_FILES} -) + ${MATH_SOURCE_FILES} ${MATH_HEADER_FILES}) +target_include_directories( KGeoBagMath + PUBLIC $ $) target_link_libraries( KGeoBagMath - ${Kommon_LIBRARIES} - ${GSL_LIBRARIES} + PUBLIC + Kommon ) # install diff --git a/KGeoBag/Source/Math/Include/KThreeMatrix.hh b/KGeoBag/Source/Math/Include/KThreeMatrix.hh index 46cc492df..84417fc1c 100644 --- a/KGeoBag/Source/Math/Include/KThreeMatrix.hh +++ b/KGeoBag/Source/Math/Include/KThreeMatrix.hh @@ -66,6 +66,15 @@ class KThreeMatrix double& operator()(int aRow, int aColumn); const double& operator()(int aRow, int aColumn) const; + double& At(int anIndex); + const double& At(int anIndex) const; + + double& At(int aRow, int aColumn); + const double& At(int aRow, int aColumn) const; + + const double* Components() const; + const std::array AsArray() const; + //properties bool IsValid() const; @@ -256,22 +265,58 @@ inline KThreeMatrix::operator const double*() const inline double& KThreeMatrix::operator[](int anIndex) { + assert(anIndex >= 0 && anIndex < 9); return fData[anIndex]; } inline const double& KThreeMatrix::operator[](int anIndex) const { + assert(anIndex >= 0 && anIndex < 9); return fData[anIndex]; } inline double& KThreeMatrix::operator()(int aRow, int aColumn) { + assert(aRow >= 0 && aRow < 3 && aColumn >= 0 && aColumn < 3); return fData[3 * aRow + aColumn]; } inline const double& KThreeMatrix::operator()(int aRow, int aColumn) const { + assert(aRow >= 0 && aRow < 3 && aColumn >= 0 && aColumn < 3); return fData[3 * aRow + aColumn]; } +inline double& KThreeMatrix::At(int anIndex) +{ + assert(anIndex >= 0 && anIndex < 9); + return fData[anIndex]; +} +inline const double& KThreeMatrix::At(int anIndex) const +{ + assert(anIndex >= 0 && anIndex < 9); + return fData[anIndex]; +} +inline double& KThreeMatrix::At(int aRow, int aColumn) +{ + assert(aRow >= 0 && aRow < 3 && aColumn >= 0 && aColumn < 3); + return fData[3 * aRow + aColumn]; +} +inline const double& KThreeMatrix::At(int aRow, int aColumn) const +{ + assert(aRow >= 0 && aRow < 3 && aColumn >= 0 && aColumn < 3); + return fData[3 * aRow + aColumn]; +} + +inline const double* KThreeMatrix::Components() const +{ + return (const double*) fData; +} +inline const std::array KThreeMatrix::AsArray() const +{ + std::array tData; + std::copy(std::begin(fData), std::end(fData), std::begin(tData)); + return tData; +} + inline bool KThreeMatrix::IsValid() const { if (std::isfinite(fData[0]) && std::isfinite(fData[1]) && std::isfinite(fData[2]) && std::isfinite(fData[3]) && diff --git a/KGeoBag/Source/Math/Include/KThreeVector.hh b/KGeoBag/Source/Math/Include/KThreeVector.hh index 4e1adb836..5e3b4ca9c 100644 --- a/KGeoBag/Source/Math/Include/KThreeVector.hh +++ b/KGeoBag/Source/Math/Include/KThreeVector.hh @@ -9,7 +9,7 @@ #include #include #include -#include +#include namespace KGeoBag { @@ -78,7 +78,7 @@ class KThreeVector const double& GetZ() const; const double* Components() const; - const std::vector ComponentVector() const; + const std::array AsArray() const; //comparison @@ -286,9 +286,10 @@ inline const double* KThreeVector::Components() const { return (const double*) fData; } -inline const std::vector KThreeVector::ComponentVector() const +inline const std::array KThreeVector::AsArray() const { - std::vector tData = {fData[0], fData[1], fData[2]}; + std::array tData; + std::copy(std::begin(fData), std::end(fData), std::begin(tData)); return tData; } diff --git a/KGeoBag/Source/Math/Include/KTwoMatrix.hh b/KGeoBag/Source/Math/Include/KTwoMatrix.hh index 07211e228..5bb398a78 100644 --- a/KGeoBag/Source/Math/Include/KTwoMatrix.hh +++ b/KGeoBag/Source/Math/Include/KTwoMatrix.hh @@ -10,6 +10,12 @@ namespace KGeoBag class KTwoMatrix { + public: + static const KTwoMatrix sInvalid; + static const KTwoMatrix sZero; + + static const KTwoMatrix sIdentity; + public: KTwoMatrix(); KTwoMatrix(const double& anXX, const double& anXY, const double& aYX, const double& aYY); @@ -37,6 +43,15 @@ class KTwoMatrix double& operator()(int aRow, int aColumn); const double& operator()(int aRow, int aColumn) const; + double& At(int anIndex); + const double& At(int anIndex) const; + + double& At(int aRow, int aColumn); + const double& At(int aRow, int aColumn) const; + + const double* Components() const; + const std::array AsArray() const; + //properties KTwoMatrix Inverse() const; @@ -115,22 +130,58 @@ inline KTwoMatrix::operator double*() inline double& KTwoMatrix::operator[](int anIndex) { + assert(anIndex >= 0 && anIndex < 4); return fData[anIndex]; } inline const double& KTwoMatrix::operator[](int anIndex) const { + assert(anIndex >= 0 && anIndex < 4); return fData[anIndex]; } inline double& KTwoMatrix::operator()(int aRow, int aColumn) { + assert(aRow >= 0 && aRow < 2 && aColumn >= 0 && aColumn < 2); return fData[2 * aRow + aColumn]; } inline const double& KTwoMatrix::operator()(int aRow, int aColumn) const { + assert(aRow >= 0 && aRow < 2 && aColumn >= 0 && aColumn < 2); + return fData[2 * aRow + aColumn]; +} + +inline double& KTwoMatrix::At(int anIndex) +{ + assert(anIndex >= 0 && anIndex < 4); + return fData[anIndex]; +} +inline const double& KTwoMatrix::At(int anIndex) const +{ + assert(anIndex >= 0 && anIndex < 4); + return fData[anIndex]; +} +inline double& KTwoMatrix::At(int aRow, int aColumn) +{ + assert(aRow >= 0 && aRow < 2 && aColumn >= 0 && aColumn < 2); + return fData[2 * aRow + aColumn]; +} +inline const double& KTwoMatrix::At(int aRow, int aColumn) const +{ + assert(aRow >= 0 && aRow < 2 && aColumn >= 0 && aColumn < 2); return fData[2 * aRow + aColumn]; } +inline const double* KTwoMatrix::Components() const +{ + return (const double*) fData; +} +inline const std::array KTwoMatrix::AsArray() const +{ + std::array tData; + std::copy(std::begin(fData), std::end(fData), std::begin(tData)); + return tData; +} + inline KTwoMatrix KTwoMatrix::Inverse() const { double tDeterminant = Determinant(); diff --git a/KGeoBag/Source/Math/Include/KTwoVector.hh b/KGeoBag/Source/Math/Include/KTwoVector.hh index b05fc5300..84156d545 100644 --- a/KGeoBag/Source/Math/Include/KTwoVector.hh +++ b/KGeoBag/Source/Math/Include/KTwoVector.hh @@ -8,7 +8,7 @@ #include #include #include -#include +#include namespace KGeoBag { @@ -75,7 +75,7 @@ class KTwoVector const double& GetR() const; const double* Components() const; - const std::vector ComponentVector() const; + const std::array AsArray() const; //comparison @@ -231,9 +231,10 @@ inline const double* KTwoVector::Components() const { return (const double*) fData; } -inline const std::vector KTwoVector::ComponentVector() const +inline const std::array KTwoVector::AsArray() const { - std::vector tData = {fData[0], fData[1]}; + std::array tData; + std::copy(std::begin(fData), std::end(fData), std::begin(tData)); return tData; } diff --git a/KGeoBag/Source/Math/LinearAlgebra/CMakeLists.txt b/KGeoBag/Source/Math/LinearAlgebra/CMakeLists.txt index e2a2665f1..2463182f0 100644 --- a/KGeoBag/Source/Math/LinearAlgebra/CMakeLists.txt +++ b/KGeoBag/Source/Math/LinearAlgebra/CMakeLists.txt @@ -17,21 +17,22 @@ set( MATH_LINALG_SOURCE_FILES Source/KGVectorOperations.cc ) -# internal -kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Include -) - # target add_library( KGeoBagMathLinearAlgebra SHARED - ${MATH_LINALG_SOURCE_FILES} ${MATH_LINALG_HEADER_FILES} + ${MATH_LINALG_SOURCE_FILES} ${MATH_LINALG_HEADER_FILES}) +target_include_directories( KGeoBagMathLinearAlgebra + PUBLIC $ $ ) target_link_libraries( KGeoBagMathLinearAlgebra - KGeoBagMath - ${Kommon_LIBRARIES} - ${GSL_LIBRARIES} + PUBLIC + KGeoBagMath ) +if(KGeoBag_USE_GSL) + target_link_libraries( KGeoBagMathLinearAlgebra PUBLIC GSL::gsl ) + target_compile_definitions( KGeoBagMathLinearAlgebra PUBLIC KGEOBAG_MATH_USE_GSL ) +endif(KGeoBag_USE_GSL) + # install kasper_install_headers( ${MATH_LINALG_HEADER_FILES} ) kasper_install_libraries( KGeoBagMathLinearAlgebra ) diff --git a/KGeoBag/Source/Math/Source/KTwoMatrix.cc b/KGeoBag/Source/Math/Source/KTwoMatrix.cc index f8adca333..9f975ce55 100644 --- a/KGeoBag/Source/Math/Source/KTwoMatrix.cc +++ b/KGeoBag/Source/Math/Source/KTwoMatrix.cc @@ -1,8 +1,16 @@ #include "KTwoMatrix.hh" +#include +const double NaN = std::numeric_limits::quiet_NaN(); + namespace KGeoBag { +const KTwoMatrix KTwoMatrix::sInvalid = KTwoMatrix(NaN, NaN, NaN, NaN); +const KTwoMatrix KTwoMatrix::sZero = KTwoMatrix(0., 0., 0., 0.); + +const KTwoMatrix KTwoMatrix::sIdentity = KTwoMatrix(1., 0., 0., 1.); + KTwoMatrix::KTwoMatrix() { fData[0] = 0.; diff --git a/KGeoBag/Source/Math/SpaceTree/CMakeLists.txt b/KGeoBag/Source/Math/SpaceTree/CMakeLists.txt index 4866d305a..245df2989 100644 --- a/KGeoBag/Source/Math/SpaceTree/CMakeLists.txt +++ b/KGeoBag/Source/Math/SpaceTree/CMakeLists.txt @@ -34,18 +34,15 @@ set( MATH_SPACETREE_SOURCE_FILES Source/KGIdentitySet.cc ) -# internal -kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Include -) - # target add_library( KGeoBagMathSpaceTree SHARED - ${MATH_SPACETREE_SOURCE_FILES} ${MATH_SPACETREE_HEADER_FILES} -) + ${MATH_SPACETREE_SOURCE_FILES} ${MATH_SPACETREE_HEADER_FILES}) +target_include_directories( KGeoBagMathSpaceTree + PUBLIC $ $) target_link_libraries( KGeoBagMathSpaceTree - ${Kommon_LIBRARIES} - ${GSL_LIBRARIES} + PUBLIC + Kommon + KGeoBagMathLinearAlgebra ) # install diff --git a/KGeoBag/Source/Shapes/Basic/Include/KGTriangle.hh b/KGeoBag/Source/Shapes/Basic/Include/KGTriangle.hh new file mode 100644 index 000000000..50fc34670 --- /dev/null +++ b/KGeoBag/Source/Shapes/Basic/Include/KGTriangle.hh @@ -0,0 +1,107 @@ +#ifndef KGTRIANGLE_H_ +#define KGTRIANGLE_H_ + +#include "KGArea.hh" + +namespace KGeoBag +{ +class KGTriangle : public KGArea +{ + public: + class Visitor + { + public: + Visitor() = default; + virtual ~Visitor() = default; + + virtual void Visit(KGTriangle*) = 0; + }; + + KGTriangle() = default; + KGTriangle(const double& a, const double& b, const KGeoBag::KThreeVector& p0, const KGeoBag::KThreeVector& n1, + const KGeoBag::KThreeVector& n2); + + KGTriangle(const KGeoBag::KThreeVector& p0, const KGeoBag::KThreeVector& p1, const KGeoBag::KThreeVector& p2); + KGTriangle(const KGTriangle&); + KGTriangle& operator=(const KGTriangle&); + + ~KGTriangle() override = default; + + void AreaInitialize() const override {} + void AreaAccept(KGVisitor* aVisitor) override; + bool AreaAbove(const KGeoBag::KThreeVector& aPoint) const override; + KGeoBag::KThreeVector AreaPoint(const KGeoBag::KThreeVector& aPoint) const override; + KGeoBag::KThreeVector AreaNormal(const KGeoBag::KThreeVector& aPoint) const override; + + void SetA(double d) + { + fA = d; + } + void SetB(double d) + { + fB = d; + } + void SetP0(const KGeoBag::KThreeVector& p) + { + fP0 = p; + } + void SetN1(const KGeoBag::KThreeVector& d) + { + fN1 = d.Unit(); + } + void SetN2(const KGeoBag::KThreeVector& d) + { + fN2 = d.Unit(); + } + + double GetA() const + { + return fA; + } + double GetB() const + { + return fB; + } + const KGeoBag::KThreeVector& GetP0() const + { + return fP0; + } + const KGeoBag::KThreeVector& GetN1() const + { + return fN1; + } + const KGeoBag::KThreeVector& GetN2() const + { + return fN2; + } + const KGeoBag::KThreeVector GetN3() const + { + return fN1.Cross(fN2); + } + const KGeoBag::KThreeVector GetP1() const + { + return fP0 + fN1 * fA; + } + const KGeoBag::KThreeVector GetP2() const + { + return fP0 + fN2 * fB; + } + + virtual bool ContainsPoint(const KThreeVector& aPoint) const; + double DistanceTo(const KThreeVector& aPoint, KThreeVector& nearestPoint); + + protected: + static bool SameSide(const KGeoBag::KThreeVector& point, const KGeoBag::KThreeVector& A, + const KGeoBag::KThreeVector& B, const KGeoBag::KThreeVector& C); + + protected: + double fA; + double fB; + KGeoBag::KThreeVector fP0; + KGeoBag::KThreeVector fN1; + KGeoBag::KThreeVector fN2; + +}; +} // namespace KGeoBag + +#endif diff --git a/KGeoBag/Source/Shapes/Basic/Source/KGTriangle.cc b/KGeoBag/Source/Shapes/Basic/Source/KGTriangle.cc new file mode 100644 index 000000000..26a67407b --- /dev/null +++ b/KGeoBag/Source/Shapes/Basic/Source/KGTriangle.cc @@ -0,0 +1,316 @@ +#include "KGTriangle.hh" + +namespace KGeoBag +{ + +KGTriangle::KGTriangle(const double& a, const double& b, const KThreeVector& p0, const KThreeVector& n1, + const KThreeVector& n2) : + fA(a), + fB(b), + fP0(p0), + fN1(n1), + fN2(n2) +{} + +KGTriangle::KGTriangle(const KThreeVector& p0, const KThreeVector& p1, const KThreeVector& p2) +{ + fP0 = p0; + fN1 = p1 - p0; + fA = fN1.Magnitude(); + fN1 = fN1.Unit(); + fN2 = p2 - p0; + fB = fN2.Magnitude(); + fN2 = fN2.Unit(); +} + +KGTriangle::KGTriangle(const KGTriangle& t) : + KGTriangle(t.fA, t.fB, t.fP0, t.fN1, t.fN2) +{} + +KGTriangle& KGTriangle::operator=(const KGTriangle& t) +{ + if (this == &t) + return *this; + + fA = t.fA; + fB = t.fB; + fP0 = t.fP0; + fN1 = t.fN1; + fN2 = t.fN2; + return *this; +} + +void KGTriangle::AreaAccept(KGVisitor* aVisitor) +{ + auto* tTriangleVisitor = dynamic_cast(aVisitor); + if (tTriangleVisitor != nullptr) { + tTriangleVisitor->Visit(this); + } + return; +} + +bool KGTriangle::AreaAbove(const KThreeVector& aPoint) const +{ + if ((aPoint - fP0).Dot(GetN3()) > 0.) + return true; + else + return false; +} + +KThreeVector KGTriangle::AreaPoint(const KThreeVector& aPoint) const +{ + /// TODO + + double u = (aPoint - fP0).Dot(fN1); + if (u < 0) + u = 0; + else if (u > fA) + u = fA; + + double v = (aPoint - fP0).Dot(fN2); + if (v < 0) + v = 0; + else if (v > fB) + v = fB; + + return fP0 + u * fN1 + v * fN2; +} + +KThreeVector KGTriangle::AreaNormal(const KThreeVector& aPoint) const +{ + KThreeVector n3 = GetN3(); + if ((aPoint - fP0).Dot(n3) > 0.) + return n3; + else + return -1. * n3; +} + +bool KGTriangle::ContainsPoint(const KThreeVector& aPoint) const +{ + KThreeVector p0 = GetP0(); + KThreeVector p1 = GetP1(); + KThreeVector p2 = GetP2(); + if (SameSide(aPoint, p0, p1, p2) && SameSide(aPoint, p1, p0, p2) && SameSide(aPoint, p2, p0, p1)) + return true; + else + return false; +} + +/** + * Returns the minimum distance between the triangle and a point P. + * This code is adapted from: "Distance Between Point and Triangle in 3D", + * David Eberly, Geometric Tools, LLC (http://www.geometrictools.com/). + */ +double KGTriangle::DistanceTo(const KThreeVector& aPoint, KThreeVector& nearestPoint) +{ + double a = fA * fA; + double b = fA * fB * fN1.Dot(fN2); + double c = fB * fB; + double d = fA * fN1.Dot(fP0 - aPoint); + double e = fB * fN2.Dot(fP0 - aPoint); + double f = (fP0 - aPoint).MagnitudeSquared(); + + int region; + + double distance; + + double det = fabs(a * c - b * b); + double s = b * e - c * d; + double t = b * d - a * e; + + if ((s + t) <= det) { + if (s < 0) { + if (t < 0) + region = 4; + else + region = 3; + } + else if (t < 0) + region = 5; + else + region = 0; + } + else { + if (s < 0) + region = 2; + else if (t < 0) + region = 6; + else + region = 1; + } + + switch (region) { + case 0: { + double invDet = 1. / det; + s *= invDet; + t *= invDet; + double val = s * (a * s + b * t + 2. * d) + t * (b * s + c * t + 2. * e) + f; + if (val < 1.e-14) + distance = 0.; + else + distance = sqrt(val); + } break; + case 1: { + double numerator = (c + e - b - d); + if (numerator <= 0.) { + s = 0.; + t = 1.; + distance = sqrt(c + 2. * e + f); + } + else { + double denominator = a - 2. * b + c; + if (numerator >= denominator) { + s = 1.; + t = 0.; + distance = sqrt(a + 2. * d + f); + } + else { + s = numerator / denominator; + t = 1. - s; + distance = sqrt(s * (a * s + b * t + 2. * d) + t * (b * s + c * t + 2. * e) + f); + } + } + } break; + case 2: { + double tmp0 = b + d; + double tmp1 = c + e; + if (tmp1 > tmp0) { + double numerator = tmp1 - tmp0; + double denominator = a - 2. * b + c; + if (numerator >= denominator) { + s = 1.; + t = 0.; + distance = sqrt(a + 2. * d + f); + } + else { + s = numerator / denominator; + t = 1. - s; + distance = sqrt(s * (a * s + b * t + 2. * d) + t * (b * s + c * t + 2. * e) + f); + } + } + else { + s = 0.; + if (tmp1 <= 0.) { + t = 1.; + distance = sqrt(c + 2. * e + f); + } + else if (e >= 0) { + t = 0.; + distance = sqrt(f); + } + else { + t = -e / c; + distance = sqrt(e * t + f); + } + } + } break; + case 3: { + s = 0.; + if (e >= 0) { + t = 0; + distance = sqrt(f); + } + else if (-e >= c) { + t = 1.; + distance = sqrt(c + 2. * e + f); + } + else { + t = -e / c; + distance = sqrt(e * t + f); + } + } break; + case 4: { + if (d < 0) { + t = 0.; + if (-d >= a) { + s = 1.; + distance = sqrt(a + 2. * d + f); + } + else { + s = -d / a; + distance = sqrt(d * s + f); + } + } + else { + s = 0.; + if (e >= 0.) { + t = 0.; + distance = sqrt(f); + } + else if (-e >= c) { + t = 1.; + distance = sqrt(c + 2. * e + f); + } + else { + t = -e / c; + distance = sqrt(c + 2. * e + f); + } + } + } break; + case 5: { + t = 0.; + if (d >= 0) { + s = 0.; + distance = sqrt(f); + } + else if (-d >= a) { + s = 1.; + distance = sqrt(a + 2. * d + f); + } + else { + s = -d / a; + distance = sqrt(d * s + f); + } + } break; + case 6: { + double tmp0 = b + e; + double tmp1 = a + d; + if (tmp1 > tmp0) { + double numerator = tmp1 - tmp0; + double denominator = a - 2. * b + c; + if (numerator >= denominator) { + t = 1.; + s = 0.; + distance = sqrt(c + 2. * e + f); + } + else { + t = numerator / denominator; + s = 1. - t; + distance = sqrt(s * (a * s + b * t + 2. * d) + t * (b * s + c * t + 2. * e) + f); + } + } + else { + t = 0.; + if (tmp1 <= 0.) { + s = 1.; + distance = sqrt(a + 2. * d + f); + } + else if (d >= 0) { + s = 0.; + distance = sqrt(f); + } + else { + s = -d / a; + distance = sqrt(d * s + f); + } + } + } break; + } + + nearestPoint = fP0 + fA * s * fN1 + fB * t * fN2; + + return distance; +} + +bool KGTriangle::SameSide(const KThreeVector& point, const KThreeVector& A, const KThreeVector& B, + const KThreeVector& C) +{ + KThreeVector cp1 = (B - A).Cross(point - A); + KThreeVector cp2 = (B - A).Cross(C - A); + if (cp1.Dot(cp2) > 0) { + return true; + } + return false; +} + +} diff --git a/KGeoBag/Source/Shapes/CMakeLists.txt b/KGeoBag/Source/Shapes/CMakeLists.txt index 178e50fd3..9b37f4109 100644 --- a/KGeoBag/Source/Shapes/CMakeLists.txt +++ b/KGeoBag/Source/Shapes/CMakeLists.txt @@ -1,44 +1,50 @@ # headers set( SHAPES_HEADER_FILES - # utilities - Utility/Include/KGShapeMessage.hh - - # basic shapes - Basic/Include/KGBox.hh - Basic/Include/KGRectangle.hh - Basic/Include/KGDisk.hh - Basic/Include/KGCylinder.hh - - # planar paths - PlanarShapes/Include/KGPlanarPath.hh - PlanarShapes/Include/KGPlanarOpenPath.hh - PlanarShapes/Include/KGPlanarLineSegment.hh - PlanarShapes/Include/KGPlanarArcSegment.hh - PlanarShapes/Include/KGPlanarPolyLine.hh - PlanarShapes/Include/KGPlanarClosedPath.hh - PlanarShapes/Include/KGPlanarCircle.hh - PlanarShapes/Include/KGPlanarPolyLoop.hh - - # flattened closed path surfaces - FlattenedAreas/Include/KGFlattenedClosedPathSurface.hh - FlattenedAreas/Include/KGFlattenedCircleSurface.hh - FlattenedAreas/Include/KGFlattenedPolyLoopSurface.hh - - # rotated path surfaces - RotatedAreas/Include/KGRotatedPathSurface.hh - RotatedAreas/Include/KGRotatedLineSegmentSurface.hh - RotatedAreas/Include/KGDiskSurface.hh - RotatedAreas/Include/KGAnnulusSurface.hh - RotatedAreas/Include/KGCylinderSurface.hh - RotatedAreas/Include/KGConeSurface.hh - RotatedAreas/Include/KGCutConeSurface.hh - RotatedAreas/Include/KGRotatedArcSegmentSurface.hh - RotatedAreas/Include/KGCutTorusSurface.hh - RotatedAreas/Include/KGRotatedPolyLineSurface.hh - RotatedAreas/Include/KGRotatedCircleSurface.hh - RotatedAreas/Include/KGTorusSurface.hh - RotatedAreas/Include/KGRotatedPolyLoopSurface.hh - + # utilities + Utility/Include/KGShapeMessage.hh + + # external shapes + External/Include/KGStlFile.hh + External/Include/KGStlFileSpace.hh + External/Include/KGStlFileSurface.hh + + # basic shapes + Basic/Include/KGBox.hh + Basic/Include/KGCylinder.hh + Basic/Include/KGDisk.hh + Basic/Include/KGRectangle.hh + Basic/Include/KGTriangle.hh + + # planar paths + PlanarShapes/Include/KGPlanarPath.hh + PlanarShapes/Include/KGPlanarOpenPath.hh + PlanarShapes/Include/KGPlanarLineSegment.hh + PlanarShapes/Include/KGPlanarArcSegment.hh + PlanarShapes/Include/KGPlanarPolyLine.hh + PlanarShapes/Include/KGPlanarClosedPath.hh + PlanarShapes/Include/KGPlanarCircle.hh + PlanarShapes/Include/KGPlanarPolyLoop.hh + + # flattened closed path surfaces + FlattenedAreas/Include/KGFlattenedClosedPathSurface.hh + FlattenedAreas/Include/KGFlattenedCircleSurface.hh + FlattenedAreas/Include/KGFlattenedPolyLoopSurface.hh + + # rotated path surfaces + RotatedAreas/Include/KGRotatedPathSurface.hh + RotatedAreas/Include/KGRotatedLineSegmentSurface.hh + RotatedAreas/Include/KGDiskSurface.hh + RotatedAreas/Include/KGAnnulusSurface.hh + RotatedAreas/Include/KGCylinderSurface.hh + RotatedAreas/Include/KGConeSurface.hh + RotatedAreas/Include/KGCutConeSurface.hh + RotatedAreas/Include/KGRotatedArcSegmentSurface.hh + RotatedAreas/Include/KGCutTorusSurface.hh + RotatedAreas/Include/KGRotatedPolyLineSurface.hh + RotatedAreas/Include/KGRotatedCircleSurface.hh + RotatedAreas/Include/KGTorusSurface.hh + RotatedAreas/Include/KGRotatedPolyLoopSurface.hh + # shell path surfaces ShellAreas/Include/KGShellPathSurface.hh ShellAreas/Include/KGShellLineSegmentSurface.hh @@ -46,68 +52,68 @@ set( SHAPES_HEADER_FILES ShellAreas/Include/KGShellPolyLineSurface.hh ShellAreas/Include/KGShellPolyLoopSurface.hh ShellAreas/Include/KGShellCircleSurface.hh - - # extruded path surfaces - ExtrudedAreas/Include/KGExtrudedPathSurface.hh - ExtrudedAreas/Include/KGExtrudedLineSegmentSurface.hh - ExtrudedAreas/Include/KGExtrudedArcSegmentSurface.hh - ExtrudedAreas/Include/KGExtrudedPolyLineSurface.hh - ExtrudedAreas/Include/KGExtrudedCircleSurface.hh - ExtrudedAreas/Include/KGExtrudedPolyLoopSurface.hh - - # rotated open path spaces - RotatedVolumes/Include/KGRotatedOpenPathSpace.hh - RotatedVolumes/Include/KGRotatedLineSegmentSpace.hh - RotatedVolumes/Include/KGCylinderSpace.hh - RotatedVolumes/Include/KGConeSpace.hh - RotatedVolumes/Include/KGCutConeSpace.hh - RotatedVolumes/Include/KGRotatedArcSegmentSpace.hh - RotatedVolumes/Include/KGRotatedPolyLineSpace.hh - - # rotated closed path spaces - RotatedVolumes/Include/KGRotatedClosedPathSpace.hh - RotatedVolumes/Include/KGRotatedCircleSpace.hh - RotatedVolumes/Include/KGTorusSpace.hh - RotatedVolumes/Include/KGRotatedPolyLoopSpace.hh - RotatedVolumes/Include/KGCylinderTubeSpace.hh - RotatedVolumes/Include/KGCutConeTubeSpace.hh - - # extruded closed path spaces - ExtrudedVolumes/Include/KGExtrudedClosedPathSpace.hh - ExtrudedVolumes/Include/KGExtrudedCircleSpace.hh - ExtrudedVolumes/Include/KGExtrudedPolyLoopSpace.hh - ExtrudedVolumes/Include/KGBoxSpace.hh - - # complex shapes - Complex/Include/KGWrappedSurface.hh - Complex/Include/KGWrappedSpace.hh - Complex/Include/KGExtrudedObject.hh - Complex/Include/KGExtrudedSurface.hh - Complex/Include/KGExtrudedSpace.hh - Complex/Include/KGRotatedObject.hh - Complex/Include/KGRotatedSurface.hh - Complex/Include/KGRotatedSpace.hh - Complex/Include/KGConicalWireArray.hh - Complex/Include/KGConicalWireArraySurface.hh - Complex/Include/KGConicalWireArraySpace.hh - Complex/Include/KGConicSectPortHousing.hh - Complex/Include/KGConicSectPortHousingSurface.hh - Complex/Include/KGConicSectPortHousingSpace.hh - Complex/Include/KGPortHousing.hh - Complex/Include/KGPortHousingSurface.hh - Complex/Include/KGPortHousingSpace.hh - Complex/Include/KGBeam.hh - Complex/Include/KGBeamSurface.hh - Complex/Include/KGBeamSpace.hh - Complex/Include/KGRod.hh - Complex/Include/KGRodSurface.hh - Complex/Include/KGRodSpace.hh - Complex/Include/KGComplexAnnulus.hh - Complex/Include/KGComplexAnnulusSurface.hh - Complex/Include/KGLinearWireGrid.hh - Complex/Include/KGLinearWireGridSurface.hh - Complex/Include/KGLinearWireGridSpace.hh - Complex/Include/KGQuadraticWireGrid.hh + + # extruded path surfaces + ExtrudedAreas/Include/KGExtrudedPathSurface.hh + ExtrudedAreas/Include/KGExtrudedLineSegmentSurface.hh + ExtrudedAreas/Include/KGExtrudedArcSegmentSurface.hh + ExtrudedAreas/Include/KGExtrudedPolyLineSurface.hh + ExtrudedAreas/Include/KGExtrudedCircleSurface.hh + ExtrudedAreas/Include/KGExtrudedPolyLoopSurface.hh + + # rotated open path spaces + RotatedVolumes/Include/KGRotatedOpenPathSpace.hh + RotatedVolumes/Include/KGRotatedLineSegmentSpace.hh + RotatedVolumes/Include/KGCylinderSpace.hh + RotatedVolumes/Include/KGConeSpace.hh + RotatedVolumes/Include/KGCutConeSpace.hh + RotatedVolumes/Include/KGRotatedArcSegmentSpace.hh + RotatedVolumes/Include/KGRotatedPolyLineSpace.hh + + # rotated closed path spaces + RotatedVolumes/Include/KGRotatedClosedPathSpace.hh + RotatedVolumes/Include/KGRotatedCircleSpace.hh + RotatedVolumes/Include/KGTorusSpace.hh + RotatedVolumes/Include/KGRotatedPolyLoopSpace.hh + RotatedVolumes/Include/KGCylinderTubeSpace.hh + RotatedVolumes/Include/KGCutConeTubeSpace.hh + + # extruded closed path spaces + ExtrudedVolumes/Include/KGExtrudedClosedPathSpace.hh + ExtrudedVolumes/Include/KGExtrudedCircleSpace.hh + ExtrudedVolumes/Include/KGExtrudedPolyLoopSpace.hh + ExtrudedVolumes/Include/KGBoxSpace.hh + + # complex shapes + Complex/Include/KGWrappedSurface.hh + Complex/Include/KGWrappedSpace.hh + Complex/Include/KGExtrudedObject.hh + Complex/Include/KGExtrudedSurface.hh + Complex/Include/KGExtrudedSpace.hh + Complex/Include/KGRotatedObject.hh + Complex/Include/KGRotatedSurface.hh + Complex/Include/KGRotatedSpace.hh + Complex/Include/KGConicalWireArray.hh + Complex/Include/KGConicalWireArraySurface.hh + Complex/Include/KGConicalWireArraySpace.hh + Complex/Include/KGConicSectPortHousing.hh + Complex/Include/KGConicSectPortHousingSurface.hh + Complex/Include/KGConicSectPortHousingSpace.hh + Complex/Include/KGPortHousing.hh + Complex/Include/KGPortHousingSurface.hh + Complex/Include/KGPortHousingSpace.hh + Complex/Include/KGBeam.hh + Complex/Include/KGBeamSurface.hh + Complex/Include/KGBeamSpace.hh + Complex/Include/KGRod.hh + Complex/Include/KGRodSurface.hh + Complex/Include/KGRodSpace.hh + Complex/Include/KGComplexAnnulus.hh + Complex/Include/KGComplexAnnulusSurface.hh + Complex/Include/KGLinearWireGrid.hh + Complex/Include/KGLinearWireGridSurface.hh + Complex/Include/KGLinearWireGridSpace.hh + Complex/Include/KGQuadraticWireGrid.hh Complex/Include/KGQuadraticWireGridSurface.hh Complex/Include/KGQuadraticWireGridSpace.hh Complex/Include/KGCircleWire.hh @@ -123,11 +129,16 @@ set( SHAPES_SOURCE_FILES # utilities Utility/Source/KGShapeMessage.cc + # external shapes + External/Source/KGStlFile.cc + External/Source/stl_reader.h + # basic shapes Basic/Source/KGBox.cc - Basic/Source/KGRectangle.cc - Basic/Source/KGDisk.cc Basic/Source/KGCylinder.cc + Basic/Source/KGDisk.cc + Basic/Source/KGRectangle.cc + Basic/Source/KGTriangle.cc # planar paths PlanarShapes/Source/KGPlanarPath.cc @@ -139,10 +150,10 @@ set( SHAPES_SOURCE_FILES PlanarShapes/Source/KGPlanarCircle.cc PlanarShapes/Source/KGPlanarPolyLoop.cc - # flattened closed path surfaces + # flattened closed path surfaces FlattenedAreas/Source/KGFlattenedCircleSurface.cc FlattenedAreas/Source/KGFlattenedPolyLoopSurface.cc - + # rotated path surfaces RotatedAreas/Source/KGRotatedLineSegmentSurface.cc RotatedAreas/Source/KGDiskSurface.cc @@ -163,35 +174,35 @@ set( SHAPES_SOURCE_FILES ShellAreas/Source/KGShellPolyLineSurface.cc ShellAreas/Source/KGShellPolyLoopSurface.cc ShellAreas/Source/KGShellCircleSurface.cc - + # extruded path surfaces ExtrudedAreas/Source/KGExtrudedLineSegmentSurface.cc ExtrudedAreas/Source/KGExtrudedArcSegmentSurface.cc ExtrudedAreas/Source/KGExtrudedPolyLineSurface.cc ExtrudedAreas/Source/KGExtrudedCircleSurface.cc ExtrudedAreas/Source/KGExtrudedPolyLoopSurface.cc - + # rotated open path spaces - RotatedVolumes/Source/KGRotatedLineSegmentSpace.cc + RotatedVolumes/Source/KGRotatedLineSegmentSpace.cc RotatedVolumes/Source/KGCylinderSpace.cc RotatedVolumes/Source/KGConeSpace.cc RotatedVolumes/Source/KGCutConeSpace.cc RotatedVolumes/Source/KGRotatedArcSegmentSpace.cc RotatedVolumes/Source/KGRotatedPolyLineSpace.cc - + # rotated closed path spaces RotatedVolumes/Source/KGRotatedCircleSpace.cc RotatedVolumes/Source/KGTorusSpace.cc RotatedVolumes/Source/KGRotatedPolyLoopSpace.cc RotatedVolumes/Source/KGCylinderTubeSpace.cc RotatedVolumes/Source/KGCutConeTubeSpace.cc - + # extruded closed path spaces ExtrudedVolumes/Source/KGExtrudedCircleSpace.cc ExtrudedVolumes/Source/KGExtrudedPolyLoopSpace.cc ExtrudedVolumes/Source/KGBoxSpace.cc - - + + Complex/Source/KGExtrudedObject.cc Complex/Source/KGRotatedObject.cc Complex/Source/KGPortHousing.cc @@ -210,34 +221,22 @@ set( SHAPES_SOURCE_FILES Complex/Source/KGComplexAnnulus.cc ) -# internal -kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Basic/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Complex/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Utility/Include - ${CMAKE_CURRENT_SOURCE_DIR}/PlanarShapes/Include - ${CMAKE_CURRENT_SOURCE_DIR}/FlattenedAreas/Include - ${CMAKE_CURRENT_SOURCE_DIR}/RotatedAreas/Include - ${CMAKE_CURRENT_SOURCE_DIR}/RotatedVolumes/Include - ${CMAKE_CURRENT_SOURCE_DIR}/ExtrudedAreas/Include - ${CMAKE_CURRENT_SOURCE_DIR}/ExtrudedVolumes/Include - ${CMAKE_CURRENT_SOURCE_DIR}/ShellAreas/Include -) - # target add_library( KGeoBagShapes SHARED - ${SHAPES_SOURCE_FILES} ${SHAPES_HEADER_FILES} -) + ${SHAPES_SOURCE_FILES} ${SHAPES_HEADER_FILES}) + +# get header paths from collected header files +foreach(HEADER ${SHAPES_HEADER_FILES}) + get_filename_component(DIRNAME ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER} DIRECTORY) + target_include_directories(KGeoBagShapes PUBLIC $) +endforeach(HEADER) +target_include_directories(KGeoBagShapes PUBLIC $) + target_link_libraries( KGeoBagShapes - ${Kommon_LIBRARIES} - KGeoBagMath - KGeoBagCore + PUBLIC + KGeoBagCore ) # install -kasper_install_headers( - ${SHAPES_HEADER_FILES} -) -kasper_install_libraries( - KGeoBagShapes -) +kasper_install_headers( ${SHAPES_HEADER_FILES} ) +kasper_install_libraries( KGeoBagShapes ) diff --git a/KGeoBag/Source/Shapes/Complex/Include/KGExtrudedObject.hh b/KGeoBag/Source/Shapes/Complex/Include/KGExtrudedObject.hh index 6945d91e4..aaeab3e45 100644 --- a/KGeoBag/Source/Shapes/Complex/Include/KGExtrudedObject.hh +++ b/KGeoBag/Source/Shapes/Complex/Include/KGExtrudedObject.hh @@ -18,8 +18,12 @@ class KGExtrudedObject : public KGBoundary fZMax(0.), fNDisc(0), fDiscretizationPower(2.), + fExtrudedMeshCount(0), + fExtrudedMeshPower(2.), fNInnerSegments(0), fNOuterSegments(0), + fRefineMesh(false), + fMeshMergeDistance(1.E-4), fClosedLoops(false), fBackwards(false) {} @@ -28,8 +32,12 @@ class KGExtrudedObject : public KGBoundary fZMax(zMax), fNDisc(nDisc), fDiscretizationPower(2.), + fExtrudedMeshCount(nDisc), + fExtrudedMeshPower(2.), fNInnerSegments(0), fNOuterSegments(0), + fRefineMesh(false), + fMeshMergeDistance(1.E-4), fClosedLoops(closedLoops), fBackwards(false) {} @@ -68,6 +76,22 @@ class KGExtrudedObject : public KGBoundary { fNDisc = ndisc; } + void SetExtrudedMeshPower(double d) + { + fExtrudedMeshPower = d; + } + void SetExtrudedMeshCount(int ndisc) + { + fExtrudedMeshCount = ndisc; + } + void SetRefineMesh(bool enable = true) + { + fRefineMesh = enable; + } + void SetMeshMergeDistance(double dist) + { + fMeshMergeDistance = dist; + } void Open() { fClosedLoops = false; @@ -106,6 +130,22 @@ class KGExtrudedObject : public KGBoundary { return fDiscretizationPower; } + int GetExtrudedMeshCount() const + { + return fExtrudedMeshCount; + } + double GetExtrudedMeshPower() const + { + return fExtrudedMeshPower; + } + bool RefineMesh() const + { + return fRefineMesh; + } + double MeshMergeDistance() const + { + return fMeshMergeDistance; + } bool ClosedLoops() const { return fClosedLoops; @@ -327,16 +367,24 @@ class KGExtrudedObject : public KGBoundary double fZMin; // Downstream z position of the surface double fZMax; - // Number of discretizations in the z-direction + // Number of discretizations in the xy-direction int fNDisc; - // Power of discretization in the z-direction + // Power of discretization in the xy-direction double fDiscretizationPower; + // Number of discretizations in the z-direction + int fExtrudedMeshCount; + // Power of discretization in the z-direction + double fExtrudedMeshPower; // # of segments that comprise the 2-D image int fNInnerSegments; // # of segments that comprise the 2-D image int fNOuterSegments; + // parameters to enable auto-refinement of the mesh + bool fRefineMesh; + double fMeshMergeDistance; + // parameter to determine whether the inner and outer segments are closed // forms bool fClosedLoops; diff --git a/KGeoBag/Source/Shapes/Complex/Source/KGExtrudedObject.cc b/KGeoBag/Source/Shapes/Complex/Source/KGExtrudedObject.cc index 3915d9a9f..c44781355 100644 --- a/KGeoBag/Source/Shapes/Complex/Source/KGExtrudedObject.cc +++ b/KGeoBag/Source/Shapes/Complex/Source/KGExtrudedObject.cc @@ -23,6 +23,8 @@ KGExtrudedObject* KGExtrudedObject::Clone() const tClone->fDiscretizationPower = fDiscretizationPower; tClone->fNInnerSegments = fNInnerSegments; tClone->fNOuterSegments = fNOuterSegments; + tClone->fRefineMesh = fRefineMesh; + tClone->fMeshMergeDistance = fMeshMergeDistance; tClone->fClosedLoops = fClosedLoops; for (auto* segment : fInnerSegments) diff --git a/KGeoBag/Source/Shapes/External/Include/KGStlFile.hh b/KGeoBag/Source/Shapes/External/Include/KGStlFile.hh new file mode 100644 index 000000000..55c993321 --- /dev/null +++ b/KGeoBag/Source/Shapes/External/Include/KGStlFile.hh @@ -0,0 +1,91 @@ +/** + * @file KGStlFile.hh + * @author Jan Behrens + * @date 2021-07-02 + */ + +#ifndef KGSTLFILE_HH +#define KGSTLFILE_HH + +#include "KGCore.hh" +#include "KGTriangle.hh" + +#include + +namespace KGeoBag +{ + +class KGStlFile : public KGBoundary +{ +public: + KGStlFile(); + ~KGStlFile() override; + + static std::string Name() + { + return "stl_file"; + } + + virtual void Initialize() const; + void AreaInitialize() const override + { + Initialize(); + } + + virtual KGStlFile* Clone() const; + + void SetFile(const std::string& aFile); + void SetPath(const std::string& aPath); + + bool ContainsPoint(const double* P) const; + double DistanceTo(const double* P, double* P_in = nullptr, double* P_norm = nullptr) const; + + void SetNDisc(int i) + { + fNDisc = i; + } + int GetNDisc() const + { + return fNDisc; + } + + void SetScaleFactor(double s = 1.) + { + fScaleFactor = s; + } + + size_t GetNumElements() const { + return fElements.size(); + } + size_t GetNumSolids() const { + return fSolids.size(); + } + size_t GetNumSolidElements() const { + return std::accumulate(fSolids.begin(), fSolids.end(), 0, + [&](size_t c, auto& s){ return c + s.size(); }); + } + + void SelectCell(size_t index); + void SelectCellRange(size_t firstIndex, size_t lastIndex); + + std::vector GetElements() const { return fElements; } + std::vector> GetSolids() const { return fSolids; } + +protected: + void ReadStlFile() const; + bool IsCellSelected(size_t index) const; + +private: + std::string fFile; + std::string fPath; + int fNDisc; + double fScaleFactor; + + std::set> fSelectedIndices; + mutable std::vector fElements; + mutable std::vector> fSolids; +}; + +} + +#endif //KGSTLFILE_HH diff --git a/KGeoBag/Source/Shapes/External/Include/KGStlFileSpace.hh b/KGeoBag/Source/Shapes/External/Include/KGStlFileSpace.hh new file mode 100644 index 000000000..242b34872 --- /dev/null +++ b/KGeoBag/Source/Shapes/External/Include/KGStlFileSpace.hh @@ -0,0 +1,20 @@ +/** + * @file KGStlFileSpace.hh + * @author Jan Behrens + * @date 2021-07-02 + */ + +#ifndef KGSTLFILESPACE_HH_ +#define KGSTLFILESPACE_HH_ + +#include "KGStlFile.hh" +#include "KGWrappedSpace.hh" + +namespace KGeoBag +{ + +typedef KGWrappedSpace KGStlFileSpace; + +} + +#endif diff --git a/KGeoBag/Source/Shapes/External/Include/KGStlFileSurface.hh b/KGeoBag/Source/Shapes/External/Include/KGStlFileSurface.hh new file mode 100644 index 000000000..085cccaf6 --- /dev/null +++ b/KGeoBag/Source/Shapes/External/Include/KGStlFileSurface.hh @@ -0,0 +1,20 @@ +/** + * @file KGStlFileSurface.hh + * @author Jan Behrens + * @date 2021-07-02 + */ + +#ifndef KGSTLFILESURFACE_HH_ +#define KGSTLFILESURFACE_HH_ + +#include "KGStlFile.hh" +#include "KGWrappedSurface.hh" + +namespace KGeoBag +{ + +typedef KGWrappedSurface KGStlFileSurface; + +} + +#endif diff --git a/KGeoBag/Source/Shapes/External/Source/KGStlFile.cc b/KGeoBag/Source/Shapes/External/Source/KGStlFile.cc new file mode 100644 index 000000000..177ca51d6 --- /dev/null +++ b/KGeoBag/Source/Shapes/External/Source/KGStlFile.cc @@ -0,0 +1,205 @@ +/** + * @file KGStlFile.cc + * @author Jan Behrens + * @date 2021-07-02 + */ + +#include "KGStlFile.hh" +#include "KGCoreMessage.hh" + +#include "KFile.h" +#include "stl_reader.h" + +#include + +using namespace std; +using namespace KGeoBag; + +KGStlFile::KGStlFile() : + fFile(), + fPath(), + fNDisc(0), + fScaleFactor(1.), + fSelectedIndices(), + fElements() +{} + +KGStlFile::~KGStlFile() = default; + +KGStlFile* KGStlFile::Clone() const +{ + auto clone = new KGStlFile(); + + std::cout << "cloning object: " << this << " -> " << clone << std::endl; + + clone->fFile = fFile; + clone->fPath = fPath; + clone->fNDisc = fNDisc; + clone->fScaleFactor = fScaleFactor; + clone->fSelectedIndices = fSelectedIndices; + clone->fElements = fElements; + + return clone; +} + +void KGStlFile::Initialize() const +{ + if (fInitialized) + return; + + ReadStlFile(); + + fInitialized = true; +} + +void KGStlFile::SetFile(const string& aFile) +{ + fFile = aFile; +} + +void KGStlFile::SetPath(const string& aPath) +{ + fPath = aPath; +} + +void KGStlFile::SelectCell(size_t index) +{ + fSelectedIndices.insert({ index, index }); +} + +void KGStlFile::SelectCellRange(size_t firstIndex, size_t lastIndex) +{ + fSelectedIndices.insert({ firstIndex, lastIndex }); +} + +bool KGStlFile::ContainsPoint(const double* P) const +{ + KThreeVector point(P); + for (auto & elem : fElements) { + if (elem.ContainsPoint(point)) + return true; + } + return false; +} + +double KGStlFile::DistanceTo(const double* P, double* P_in, double* P_norm) const +{ + KThreeVector point(P); + KThreeVector nearestPoint, nearestNormal; + double nearestDistance = std::numeric_limits::max(); + + for (auto & elem : fElements) { + double d = elem.DistanceTo(point, nearestPoint); + if (d < nearestDistance) { + nearestDistance = d; + nearestNormal = elem.GetN3(); + + if (P_in != nullptr) { + for (unsigned i = 0; i < 3; ++i) + P_in[i] = nearestPoint[i]; + } + + if (P_norm != nullptr) { + for (unsigned i = 0; i < 3; ++i) + P_norm[i] = nearestNormal[i]; + } + } + } + + return nearestDistance; +} + +bool KGStlFile::IsCellSelected(size_t index) const +{ + if (fSelectedIndices.empty()) + return true; + + for (auto & range : fSelectedIndices) { + if ((index >= range.first) && (index <= range.second)) + return true; + } + return false; +} + +template +KGTriangle GetTriangle(stl_reader::StlMesh& mesh, size_t index, double scale = 1.) +{ + KThreeVector p[3], n; + for (size_t icorner = 0; icorner < 3; ++icorner) { + const double* c = mesh.tri_corner_coords(index, icorner); + p[icorner] = c; + } + n = mesh.tri_normal(index); + + auto tri = KGTriangle(p[0] * scale, p[1] * scale, p[2] * scale); + if (n.Dot(tri.GetN3()) < 0) { + // normals are flipped, so change order of points + tri = KGTriangle(p[2] * scale, p[1] * scale, p[0] * scale); + } + + return tri; +} + +void KGStlFile::ReadStlFile() const +{ + string tFile; + + if (!fFile.empty()) { + if (fPath.empty()) { + tFile = string(DATA_DEFAULT_DIR) + string("/") + fFile; + } + else { + tFile = fPath + string("/") + fFile; + } + } + else { + tFile = string(DATA_DEFAULT_DIR) + string("/") + GetName() + string(".vtp"); + } + + coremsg_debug("reading elements from STL file <" << tFile << ">" << eom); + + // Adapted from https://github.com/sreiter/stl_reader + try { + stl_reader::StlMesh mesh(tFile.c_str()); + + const auto num_tris = mesh.num_tris(); + fElements.clear(); + fElements.reserve(num_tris); + + for(size_t itri = 0; itri < num_tris; ++itri) { + if (! IsCellSelected(itri)) + continue; + + KGTriangle tri = GetTriangle(mesh, itri, fScaleFactor); + fElements.emplace_back(tri); + } + + /// TODO: avoid storing triangles twice if they're in a solid + + const auto num_solids = mesh.num_solids(); + fSolids.clear(); + fSolids.reserve(num_solids); + + for (size_t isol = 0; isol < num_solids; ++isol) { + vector group; + for (size_t itri = mesh.solid_tris_begin(isol); itri < mesh.solid_tris_end(isol); ++itri) { + if (! IsCellSelected(itri)) + continue; + + KGTriangle tri = GetTriangle(mesh, itri, fScaleFactor); + group.emplace_back(tri); + } + if (! group.empty()) + fSolids.emplace_back(group); + } + + coremsg(eNormal) << "STL file <" << tFile << "> contains <" << fElements.size() + << "> triangles and <" << fSolids.size() << "> solids" << eom; + } + catch (std::exception &e) { + coremsg(eError) << "could not read from file <" << tFile << ">: " << e.what() << eom; + throw; + } + + +} diff --git a/KGeoBag/Source/Shapes/External/Source/stl_reader.h b/KGeoBag/Source/Shapes/External/Source/stl_reader.h new file mode 100644 index 000000000..065cd05dd --- /dev/null +++ b/KGeoBag/Source/Shapes/External/Source/stl_reader.h @@ -0,0 +1,721 @@ +/* + Copyright (c) 2018, Sebastian Reiter (s.b.reiter@gmail.com) + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +/** \file + * \brief Provides functions to read **stl files** into user provided arrays + * + * The central function of this file is `ReadStlFile(...)`. It automatically recognizes + * whether an *ASCII* or a *Binary* file is to be read. It identifies matching corner + * coordinates of triangles with each other, so that the resulting coordinate + * array does not contain the same coordinate-triple multiple times. + * + * The function operates on template container types. Those containers should + * have similar interfaces as `std::vector` and operate on `float` or `double` types + * (`TNumberContainer`) or on `int` or `size_t` types (`TIndexContainer`). + * + * + * A conveniance class `StlMesh` is also provided, which makes accessing triangle + * corners and corresponding corner coordinates much more easy. It still provides + * raw access to the underlying data arrays. + * + * + * ### Usage example 1 (using `StlMesh`): + * + * \code + * try { + * stl_reader::StlMesh mesh ("geometry.stl"); + * + * for(size_t itri = 0; itri < mesh.num_tris(); ++itri) { + * std::cout << "coordinates of triangle " << itri << ": "; + * for(size_t icorner = 0; icorner < 3; ++icorner) { + * const float* c = mesh.tri_corner_coords (itri, icorner); + * // or alternatively: + * // float* c = mesh.vrt_coords (mesh.tri_corner_ind (itri, icorner)); + * std::cout << "(" << c[0] << ", " << c[1] << ", " << c[2] << ") "; + * } + * std::cout << std::endl; + * + * float* n = mesh.tri_normal (itri); + * std::cout << "normal of triangle " << itri << ": " + * << "(" << n[0] << ", " << n[1] << ", " << n[2] << ")\n"; + * } + * } + * catch (std::exception& e) { + * std::cout << e.what() << std::endl; + * } + * \endcode + * + * + * ### Usage example 2 (using `StlMesh` and *solids*) + * + * \code + * try { + * stl_reader::StlMesh mesh ("geometry.stl"); + * + * for(size_t isolid = 0; isolid < mesh.num_solids(); ++isolid) { + * std::cout << "solid " << isolid << std::endl; + * + * for(size_t itri = mesh.solid_tris_begin(isolid); + * itri < mesh.solid_tris_end(isolid); ++itri) + * { + * const float* n = mesh.tri_normal (itri); + * std::cout << "normal of triangle " << itri << ": " + * << "(" << n[0] << ", " << n[1] << ", " << n[2] << ")\n"; + * } + * } + * } + * catch (std::exception& e) { + * std::cout << e.what() << std::endl; + * } + * \endcode + * + * + * ### Usage example 3 (using raw data arrays) + * + * \code + * std::vector coords, normals; + * std::vector tris, solids; + * + * try { + * stl_reader::ReadStlFile ("geometry.stl", coords, normals, tris, solids); + * const size_t numTris = tris.size() / 3; + * for(size_t itri = 0; itri < numTris; ++itri) { + * std::cout << "coordinates of triangle " << itri << ": "; + * for(size_t icorner = 0; icorner < 3; ++icorner) { + * float* c = &coords[3 * tris [3 * itri + icorner]]; + * std::cout << "(" << c[0] << ", " << c[1] << ", " << c[2] << ") "; + * } + * std::cout << std::endl; + * + * float* n = &normals [3 * itri]; + * std::cout << "normal of triangle " << itri << ": " + * << "(" << n[0] << ", " << n[1] << ", " << n[2] << ")\n"; + * } + * } + * catch (std::exception& e) { + * std::cout << e.what() << std::endl; + * } + * \endcode + * + * If you do not want to use exceptions, you may define the macro + * STL_READER_NO_EXCEPTIONS before including 'stl_reader.h'. In that case, + * functions will return `false` if an error occurred. + */ + +#ifndef __H__STL_READER +#define __H__STL_READER + +#include +#include +#include +#include +#include + +#ifdef STL_READER_NO_EXCEPTIONS + #define STL_READER_THROW(msg) return false; + #define STL_READER_COND_THROW(cond, msg) if(cond) return false; +#else + /// Throws an std::runtime_error with the given message. + #define STL_READER_THROW(msg) {std::stringstream ss; ss << msg; throw(std::runtime_error(ss.str()));} + + /// Throws an std::runtime_error with the given message, if the given condition evaluates to true. + #define STL_READER_COND_THROW(cond, msg) if(cond){std::stringstream ss; ss << msg; throw(std::runtime_error(ss.str()));} +#endif + + +namespace stl_reader { + +/// Reads an ASCII or binary stl file into several arrays +/** Reads a stl file and writes its coordinates, normals and triangle-corner-indices + * to the provided containers. It also fills a container solidRangesOut, which + * provides the triangle ranges for individual solids. + * + * Double vertex entries are removed on the fly, so that triangle corners with + * equal coordinates are represented by a single coordinate entry in coordsOut. + * + * + * \param filename [in] The name of the file which shall be read + * + * \param coordsOut [out] Coordinates are written to this container. On termination, + * it has size numVertices * 3. Each triple of entries forms a + * 3d coordinate. The type TNumberContainer should have the same + * interface as std::vector. + * + * \param normalsOut [out] Face normals are written to this container. On termination, + * it has size numFaces * 3. Each triple of entries forms a + * 3d normal. The type TNumberContainer should have the same + * interface as std::vector. + * + * \param trisOut [out] Triangle corner indices are written to this container. + * On termination, it has size numFaces * 3. Each triple of + * entries defines a triangle. The type TIndexContainer should + * have the same interface as std::vector. + * Multiply corner indices from trisOut by 3 to obtain the index + * of the first coordinate of that corner in coordsOut. + * + * \param solidRangesOut [out] On termination, it holds the ranges of triangle indices + * for each solid. It has the size numSolids + 1. Each entry + * can be interpreted as a end/begin triangle index for the + * previous/next solid. E.g., if there are 3 solids, the + * returned array would look like this: + * \code + * {sol1Begin, sol1End/sol2Begin, sol2End/sol3Begin, sol3End}. + * \endcode + * The type TIndexContainer should have the same interface + * as std::vector. + * + * \returns true if the file was successfully read into the provided container. + */ +template +bool ReadStlFile(const char* filename, + TNumberContainer1& coordsOut, + TNumberContainer2& normalsOut, + TIndexContainer1& trisOut, + TIndexContainer2& solidRangesOut); + + +/// Reads an ASCII stl file into several arrays +/** \copydetails ReadStlFile + * \sa ReadStlFile, ReadStlFile_ASCII + */ +template +bool ReadStlFile_ASCII(const char* filename, + TNumberContainer1& coordsOut, + TNumberContainer2& normalsOut, + TIndexContainer1& trisOut, + TIndexContainer2& solidRangesOut); + +/// Reads a binary stl file into several arrays +/** \copydetails ReadStlFile + * \todo support systems with big endianess + * \sa ReadStlFile, ReadStlFile_BINARY + */ +template +bool ReadStlFile_BINARY(const char* filename, + TNumberContainer1& coordsOut, + TNumberContainer2& normalsOut, + TIndexContainer1& trisOut, + TIndexContainer2& solidRangesOut); + +/// Determines whether a stl file has ASCII format +/** The underlying mechanism is simply checks whether the provided file starts + * with the keyword solid. This should work for many stl files, but may + * fail, of course. + */ +inline bool StlFileHasASCIIFormat(const char* filename); + + +/// convenience mesh class which makes accessing the stl data more easy +template +class StlMesh { +public: + /// initializes an empty mesh + StlMesh () + { + solids.resize (2, 0); + } + + /// initializes the mesh from the stl-file specified through filename + /** \{ */ + StlMesh (const char* filename) + { + read_file (filename); + } + + StlMesh (const std::string& filename) + { + read_file (filename); + } + /** \} */ + + /// fills the mesh with the contents of the specified stl-file + /** \{ */ + bool read_file (const char* filename) + { + bool res = false; + + #ifndef STL_READER_NO_EXCEPTIONS + try { + #endif + + res = ReadStlFile (filename, coords, normals, tris, solids); + + #ifndef STL_READER_NO_EXCEPTIONS + } catch (std::exception& e) { + #else + if (!res) { + #endif + + coords.clear (); + normals.clear (); + tris.clear (); + solids.clear (); + STL_READER_THROW (e.what()); + } + + return res; + } + + bool read_file (const std::string& filename) + { + return read_file (filename.c_str()); + } + /** \} */ + + /// returns the number of vertices in the mesh + size_t num_vrts () const + { + return coords.size() / 3; + } + + /// returns an array of 3 floating point values, one for each coordinate of the vertex + const TNumber* vrt_coords (const size_t vi) const + { + return &coords[vi * 3]; + } + + /// returns the number of triangles in the mesh + size_t num_tris () const + { + return tris.size() / 3; + } + + /// returns an array of 3 indices, one for each corner vertex of the triangle + const TIndex* tri_corner_inds (const size_t ti) const + { + return &tris [ti * 3]; + } + + /// returns the index of the corner with index `0<=ci<3` of triangle ti + const TIndex tri_corner_ind (const size_t ti, const size_t ci) const + { + return tris [ti * 3 + ci]; + } + + /** \brief returns an array of 3 floating point values, one for each + * coordinate of the specified corner of the specified tri. + * \note same result as calling on a `StlMesh mesh`: + * \code + * mesh.vrt_coords (mesh.tri_corner_ind (itri, icorner)) + * \endcode + */ + const TNumber* tri_corner_coords (const size_t ti, const size_t ci) const + { + return &coords[tri_corner_ind(ti, ci) * 3]; + } + + /// returns an array of 3 floating point values defining the normal of a tri + const TNumber* tri_normal (const size_t ti) const + { + return &normals [ti * 3]; + } + + /// returns the number of solids of the mesh + /** solids can be seen as a partitioning of the triangles of a mesh. + * By iterating consecutively from the index of the first triangle of a + * solid `si` (using `solid_tris_begin(si)`) to the index of the last + * triangle of a solid (using `solid_tris_end(...)-1`), one visits all + * triangles of the solid `si`.*/ + size_t num_solids () const + { + if(solids.empty ()) + return 0; + return solids.size () - 1; + } + + /// returns the index of the first triangle in the given solid + TIndex solid_tris_begin (const size_t si) const + { + return solids [si]; + } + + /// returns the index of the triangle behind the last triangle in the given solid + TIndex solid_tris_end (const size_t si) const + { + return solids [si + 1]; + } + + /// returns a pointer to the coordinate array, containing `num_vrts()*3` entries. + /** Storage layout: `x0,y0,z0,x1,y1,z1,...` + * \returns pointer to a contiguous array of numbers, or `NULL` if no coords exist.*/ + const TNumber* raw_coords () const + { + if(coords.empty()) + return NULL; + return &coords[0]; + } + + /// returns a pointer to the normal array, containing `num_tris()*3` entries. + /** Storage layout: `nx0,ny0,nz0,nx1,ny1,nz1,...` + * \returns pointer to a contiguous array of numbers, or `NULL` if no normals exist.*/ + const TNumber* raw_normals () const + { + if(normals.empty()) + return NULL; + return &normals[0]; + } + + /// returns a pointer to the triangle array, containing `num_tris()*3` entries. + /** Storage layout: `t0c0,t0c1,t0c2,t1c0,t1c1,t1c2,...` + * \returns pointer to a contiguous array of indices, or `NULL` if no tris exist.*/ + const TIndex* raw_tris () const + { + if(tris.empty()) + return NULL; + return &tris[0]; + } + + /// returns a pointer to the solids array, containing `num_solids()+1` entries. + /** Storage layout: `s0begin, s0end/s1begin, s1end/s2begin, ..., sNend` + * \returns pointer to a contiguous array of indices, or `NULL` if no solids exist.*/ + const TIndex* raw_solids () const + { + if(solids.empty()) + return NULL; + return &solids[0]; + } + +private: + std::vector coords; + std::vector normals; + std::vector tris; + std::vector solids; +}; + + +//////////////////////////////////////////////////////////////////////////////// +// IMPLEMENTATION +//////////////////////////////////////////////////////////////////////////////// + + +namespace stl_reader_impl { + + // a coordinate triple with an additional index. The index is required + // for RemoveDoubles, so that triangles can be reindexed properly. + template + struct CoordWithIndex { + number_t data[3]; + index_t index; + + bool operator == (const CoordWithIndex& c) const + { + return (c[0] == data[0]) && (c[1] == data[1]) && (c[2] == data[2]); + } + + bool operator != (const CoordWithIndex& c) const + { + return (c[0] != data[0]) || (c[1] != data[1]) || (c[2] != data[2]); + } + + bool operator < (const CoordWithIndex& c) const + { + return (data[0] < c[0]) + || (data[0] == c[0] && data[1] < c[1]) + || (data[0] == c[0] && data[1] == c[1] && data[2] < c[2]); + } + + inline number_t& operator [] (const size_t i) {return data[i];} + inline number_t operator [] (const size_t i) const {return data[i];} + }; + + // sorts the array coordsWithIndexInOut and copies unique indices to coordsOut. + // Triangle-corners are re-indexed on the fly and degenerated triangles are removed. + template + void RemoveDoubles (TNumberContainer& uniqueCoordsOut, + TIndexContainer& trisInOut, + std::vector > + &coordsWithIndexInOut) + { + using namespace std; + + typedef typename TNumberContainer::value_type number_t; + typedef typename TIndexContainer::value_type index_t; + + sort (coordsWithIndexInOut.begin(), coordsWithIndexInOut.end()); + + // first count unique indices + index_t numUnique = 1; + for(size_t i = 1; i < coordsWithIndexInOut.size(); ++i){ + if(coordsWithIndexInOut[i] != coordsWithIndexInOut[i - 1]) + ++numUnique; + } + + uniqueCoordsOut.resize (numUnique * 3); + vector newIndex (coordsWithIndexInOut.size()); + + // copy unique coordinates to 'uniqueCoordsOut' and create an index-map + // 'newIndex', which allows to re-index triangles later on. + index_t curInd = 0; + newIndex[0] = 0; + for(index_t i = 0; i < 3; ++i) + uniqueCoordsOut[i] = coordsWithIndexInOut[0][i]; + + for(size_t i = 1; i < coordsWithIndexInOut.size(); ++i){ + const CoordWithIndex c = coordsWithIndexInOut[i]; + if(c != coordsWithIndexInOut[i - 1]){ + ++curInd; + for(index_t j = 0; j < 3; ++j) + uniqueCoordsOut[curInd * 3 + j] = coordsWithIndexInOut[i][j]; + } + + newIndex[c.index] = static_cast (curInd); + } + + // re-index triangles, so that they refer to 'uniqueCoordsOut' + // make sure to only add triangles which refer to three different indices + index_t numUniqueTriInds = 0; + for(index_t i = 0; i < trisInOut.size(); i+=3){ + int ni[3]; + for(int j = 0; j < 3; ++j) + ni[j] = newIndex[trisInOut[i+j]]; + + if((ni[0] != ni[1]) && (ni[0] != ni[2]) && (ni[1] != ni[2])){ + for(int j = 0; j < 3; ++j) + trisInOut[numUniqueTriInds + j] = ni[j]; + numUniqueTriInds += 3; + } + } + + if(numUniqueTriInds < trisInOut.size()) + trisInOut.resize (numUniqueTriInds); + } +}// end of namespace stl_reader_impl + + +template +bool ReadStlFile(const char* filename, + TNumberContainer1& coordsOut, + TNumberContainer2& normalsOut, + TIndexContainer1& trisOut, + TIndexContainer2& solidRangesOut) +{ + if(StlFileHasASCIIFormat(filename)) + return ReadStlFile_ASCII(filename, coordsOut, normalsOut, trisOut, solidRangesOut); + else + return ReadStlFile_BINARY(filename, coordsOut, normalsOut, trisOut, solidRangesOut); +} + + +template +bool ReadStlFile_ASCII(const char* filename, + TNumberContainer1& coordsOut, + TNumberContainer2& normalsOut, + TIndexContainer1& trisOut, + TIndexContainer2& solidRangesOut) +{ + using namespace std; + using namespace stl_reader_impl; + + typedef typename TNumberContainer1::value_type number_t; + typedef typename TIndexContainer1::value_type index_t; + + coordsOut.clear(); + normalsOut.clear(); + trisOut.clear(); + solidRangesOut.clear(); + + ifstream in(filename); + STL_READER_COND_THROW(!in, "Couldn't open file " << filename); + + vector > coordsWithIndex; + + string buffer; + vector tokens; + int lineCount = 1; + int maxNumTokens = 0; + size_t numFaceVrts = 0; + + while(!(in.eof() || in.fail())) + { + // read the line and tokenize. + // In order to reuse memory in between lines, 'tokens' won't be cleared. + // Instead we count the number of tokens using 'tokenCount'. + getline(in, buffer); + + istringstream line(buffer); + int tokenCount = 0; + while(!(line.eof() || line.fail())){ + if(tokenCount >= maxNumTokens){ + maxNumTokens = tokenCount + 1; + tokens.resize(maxNumTokens); + } + line >> tokens[tokenCount]; + ++tokenCount; + } + + if(tokenCount > 0) + { + string& tok = tokens[0]; + if(tok.compare("vertex") == 0){ + if(tokenCount < 4){ + STL_READER_THROW("ERROR while reading from " << filename << + ": vertex not specified correctly in line " << lineCount); + } + + // read the position + CoordWithIndex c; + for(size_t i = 0; i < 3; ++i) + c[i] = static_cast (atof(tokens[i+1].c_str())); + c.index = static_cast(coordsWithIndex.size()); + coordsWithIndex.push_back(c); + ++numFaceVrts; + } + else if(tok.compare("facet") == 0) + { + STL_READER_COND_THROW(tokenCount < 5, + "ERROR while reading from " << filename << + ": triangle not specified correctly in line " << lineCount); + + STL_READER_COND_THROW(tokens[1].compare("normal") != 0, + "ERROR while reading from " << filename << + ": Missing normal specifier in line " << lineCount); + + // read the normal + for(size_t i = 0; i < 3; ++i) + normalsOut.push_back (static_cast (atof(tokens[i+2].c_str()))); + + numFaceVrts = 0; + } + else if(tok.compare("outer") == 0){ + STL_READER_COND_THROW ((tokenCount < 2) || (tokens[1].compare("loop") != 0), + "ERROR while reading from " << filename << + ": expecting outer loop in line " << lineCount); + } + else if(tok.compare("endfacet") == 0){ + STL_READER_COND_THROW(numFaceVrts != 3, + "ERROR while reading from " << filename << + ": bad number of vertices specified for face in line " << lineCount); + + trisOut.push_back(static_cast (coordsWithIndex.size() - 3)); + trisOut.push_back(static_cast (coordsWithIndex.size() - 2)); + trisOut.push_back(static_cast (coordsWithIndex.size() - 1)); + } + else if(tok.compare("solid") == 0){ + solidRangesOut.push_back(static_cast (trisOut.size() / 3)); + } + } + lineCount++; + } + + solidRangesOut.push_back(static_cast (trisOut.size() / 3)); + + RemoveDoubles (coordsOut, trisOut, coordsWithIndex); + + return true; +} + + +template +bool ReadStlFile_BINARY(const char* filename, + TNumberContainer1& coordsOut, + TNumberContainer2& normalsOut, + TIndexContainer1& trisOut, + TIndexContainer2& solidRangesOut) +{ + using namespace std; + using namespace stl_reader_impl; + + typedef typename TNumberContainer1::value_type number_t; + typedef typename TIndexContainer1::value_type index_t; + + coordsOut.clear(); + normalsOut.clear(); + trisOut.clear(); + solidRangesOut.clear(); + + ifstream in(filename, ios::binary); + STL_READER_COND_THROW(!in, "Couldnt open file " << filename); + + char stl_header[80]; + in.read(stl_header, 80); + STL_READER_COND_THROW(!in, "Error while parsing binary stl header in file " << filename); + + unsigned int numTris = 0; + in.read((char*)&numTris, 4); + STL_READER_COND_THROW(!in, "Couldnt determine number of triangles in binary stl file " << filename); + + vector > coordsWithIndex; + + for(unsigned int tri = 0; tri < numTris; ++tri){ + float d[12]; + in.read((char*)d, 12 * 4); + STL_READER_COND_THROW(!in, "Error while parsing trianlge in binary stl file " << filename); + + for(int i = 0; i < 3; ++i) + normalsOut.push_back (d[i]); + + for(size_t ivrt = 1; ivrt < 4; ++ivrt){ + CoordWithIndex c; + for(size_t i = 0; i < 3; ++i) + c[i] = d[ivrt * 3 + i]; + c.index = static_cast(coordsWithIndex.size()); + coordsWithIndex.push_back(c); + } + + trisOut.push_back(static_cast (coordsWithIndex.size() - 3)); + trisOut.push_back(static_cast (coordsWithIndex.size() - 2)); + trisOut.push_back(static_cast (coordsWithIndex.size() - 1)); + + char addData[2]; + in.read(addData, 2); + STL_READER_COND_THROW(!in, "Error while parsing additional triangle data in binary stl file " << filename); + } + + solidRangesOut.push_back(0); + solidRangesOut.push_back(static_cast (trisOut.size() / 3)); + + RemoveDoubles (coordsOut, trisOut, coordsWithIndex); + + return true; +} + + +inline bool StlFileHasASCIIFormat(const char* filename) +{ + using namespace std; + ifstream in(filename); + STL_READER_COND_THROW(!in, "Couldnt open file " << filename); + + char chars [256]; + in.read (chars, 256); + string buffer (chars, in.gcount()); + transform(buffer.begin(), buffer.end(), buffer.begin(), ::tolower); + return buffer.find ("solid") != string::npos && + buffer.find ("\n") != string::npos && + buffer.find ("facet") != string::npos && + buffer.find ("normal") != string::npos; +} + +} // end of namespace stl_reader + +#endif //__H__STL_READER diff --git a/KGeoBag/Source/Shapes/ExtrudedVolumes/Include/KGExtrudedClosedPathSpace.hh b/KGeoBag/Source/Shapes/ExtrudedVolumes/Include/KGExtrudedClosedPathSpace.hh index a5c0b8476..d340df4b7 100644 --- a/KGeoBag/Source/Shapes/ExtrudedVolumes/Include/KGExtrudedClosedPathSpace.hh +++ b/KGeoBag/Source/Shapes/ExtrudedVolumes/Include/KGExtrudedClosedPathSpace.hh @@ -152,7 +152,10 @@ template class KGExtrudedClosedPathSpace : public KGVolume aBoundaryContainer.push_back(tTop); auto tJacket = std::make_shared>(fPath); + tJacket->ZMax(fZMax); + tJacket->ZMin(fZMin); tJacket->ExtrudedMeshCount(fExtrudedMeshCount); + tJacket->ExtrudedMeshPower(fExtrudedMeshPower); tJacket->SetName("jacket"); aBoundaryContainer.push_back(tJacket); diff --git a/KGeoBag/Source/Test/CMakeLists.txt b/KGeoBag/Source/Test/CMakeLists.txt index 9cdd4f826..13c659608 100644 --- a/KGeoBag/Source/Test/CMakeLists.txt +++ b/KGeoBag/Source/Test/CMakeLists.txt @@ -1,57 +1,47 @@ -set (TEST_LIBS - KGeoBagCore - KGeoBagShapes - KGeoBagMesh - ${Kommon_LIBRARIES} - ${Kommon_Vtk_LIBRARIES} -) - -# internal -kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Basic/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Complex/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Utility/Include - ${CMAKE_CURRENT_SOURCE_DIR}/PlanarShapes/Include - ${CMAKE_CURRENT_SOURCE_DIR}/FlattenedAreas/Include - ${CMAKE_CURRENT_SOURCE_DIR}/RotatedAreas/Include - ${CMAKE_CURRENT_SOURCE_DIR}/RotatedVolumes/Include - ${CMAKE_CURRENT_SOURCE_DIR}/ExtrudedAreas/Include - ${CMAKE_CURRENT_SOURCE_DIR}/ExtrudedVolumes/Include -) - -#if(KGeoBag_USE_VTK) -#list( APPEND TEST_LIBS -# KGeoBagVisualization -# ) -#endif(KGeoBag_USE_VTK) - -#add_executable (TestKGBeam -#${CMAKE_CURRENT_SOURCE_DIR}/TestKGBeam.cc) -#target_link_libraries (TestKGBeam ${TEST_LIBS}) - -#kasper_install_executables ( -#TestKGBeam -#) - -#add_executable (TestStructure -#${CMAKE_CURRENT_SOURCE_DIR}/TestStructure.cc) -#target_link_libraries (TestStructure ${TEST_LIBS}) - -#add_executable (TestCylinders -#${CMAKE_CURRENT_SOURCE_DIR}/TestCylinders.cc) -#target_link_libraries (TestCylinders ${TEST_LIBS}) - -#add_executable (TestEMCylinders -#${CMAKE_CURRENT_SOURCE_DIR}/TestEMCylinders.cc) -#target_link_libraries (TestEMCylinders ${TEST_LIBS}) - -#add_executable (TestInterpolation -#${CMAKE_CURRENT_SOURCE_DIR}/TestInterpolation.cc) -#target_link_libraries (TestInterpolation ${TEST_LIBS} KGeoBagKatrin) - -#kasper_install_executables ( -# TestStructure -# TestCylinders -# TestEMCylinders -# TestInterpolation -#) +option (KGeoBag_ENABLE_TEST "Build KGeoBag test applications" OFF) +if (KGeoBag_ENABLE_TEST) + + set (TEST_LIBS + KGeoBagCore + KGeoBagShapes + KGeoBagMesh + ) + + if(KGeoBag_USE_VTK) + list( APPEND TEST_LIBS + KGeoBagVisualization + ) + endif(KGeoBag_USE_VTK) + + #add_executable (TestKGBeam + #${CMAKE_CURRENT_SOURCE_DIR}/TestKGBeam.cc) + #target_link_libraries (TestKGBeam ${TEST_LIBS}) + + #kasper_install_executables ( + #TestKGBeam + #) + + #add_executable (TestStructure + #${CMAKE_CURRENT_SOURCE_DIR}/TestStructure.cc) + #target_link_libraries (TestStructure ${TEST_LIBS}) + + #add_executable (TestCylinders + #${CMAKE_CURRENT_SOURCE_DIR}/TestCylinders.cc) + #target_link_libraries (TestCylinders ${TEST_LIBS}) + + #add_executable (TestEMCylinders + #${CMAKE_CURRENT_SOURCE_DIR}/TestEMCylinders.cc) + #target_link_libraries (TestEMCylinders ${TEST_LIBS}) + + #add_executable (TestInterpolation + #${CMAKE_CURRENT_SOURCE_DIR}/TestInterpolation.cc) + #target_link_libraries (TestInterpolation ${TEST_LIBS} KGeoBagKatrin) + + #kasper_install_executables ( + # TestStructure + # TestCylinders + # TestEMCylinders + # TestInterpolation + #) + +endif(KGeoBag_ENABLE_TEST) diff --git a/KGeoBag/Source/Test/CMakeListsOLD.txt b/KGeoBag/Source/Test/CMakeListsOLD.txt deleted file mode 100644 index 8bb36623f..000000000 --- a/KGeoBag/Source/Test/CMakeListsOLD.txt +++ /dev/null @@ -1,200 +0,0 @@ -set (TEST_LIBS - ${ROOT_LIBRARIES} - ${GSL_LIBRARIES} - ${BOOST_LIBRARIES} - KGeoBagShapes - KGeoBagStructure - KGeoBagDiscretization - KGeoBagVisualization - KGeoBagKatrin -) - - add_executable (Test2DPolygon - ${CMAKE_CURRENT_SOURCE_DIR}/Test2DPolygon.cc) - target_link_libraries (Test2DPolygon ${TEST_LIBS}) - - add_executable (Test2DPolygonWithArcs - ${CMAKE_CURRENT_SOURCE_DIR}/Test2DPolygonWithArcs.cc) - target_link_libraries (Test2DPolygonWithArcs ${TEST_LIBS}) - - add_executable (Test2DArc - ${CMAKE_CURRENT_SOURCE_DIR}/Test2DArc.cc) - target_link_libraries (Test2DArc ${TEST_LIBS}) - - add_executable (Test2DLineSegment - ${CMAKE_CURRENT_SOURCE_DIR}/Test2DLineSegment.cc) - target_link_libraries (Test2DLineSegment ${TEST_LIBS}) - - add_executable (TestPolygonWithArcs3d - ${CMAKE_CURRENT_SOURCE_DIR}/TestPolygonWithArcs3d.cc) - target_link_libraries (TestPolygonWithArcs3d ${TEST_LIBS}) - - add_executable (TestBeamDiscretization - ${CMAKE_CURRENT_SOURCE_DIR}/TestBeamDiscretization.cc) - target_link_libraries (TestBeamDiscretization ${TEST_LIBS}) - - add_executable (TestConicSectPortHousingDiscretization - ${CMAKE_CURRENT_SOURCE_DIR}/TestConicSectPortHousingDiscretization.cc) - target_link_libraries (TestConicSectPortHousingDiscretization ${TEST_LIBS}) - - add_executable (TestConicSectPortHousingIntersectionVTK - ${CMAKE_CURRENT_SOURCE_DIR}/TestConicSectPortHousingIntersectionVTK.cc) - target_link_libraries (TestConicSectPortHousingIntersectionVTK ${TEST_LIBS}) - - add_executable (TestExtrudedSurfaceDiscretization - ${CMAKE_CURRENT_SOURCE_DIR}/TestExtrudedSurfaceDiscretization.cc) - target_link_libraries (TestExtrudedSurfaceDiscretization ${TEST_LIBS}) - - add_executable (TestExtrudedSurfaceIntersectionVTK - ${CMAKE_CURRENT_SOURCE_DIR}/TestExtrudedSurfaceIntersectionVTK.cc) - target_link_libraries (TestExtrudedSurfaceIntersectionVTK ${TEST_LIBS}) - - add_executable (TestBeamIntersectionVTK - ${CMAKE_CURRENT_SOURCE_DIR}/TestBeamIntersectionVTK.cc) - target_link_libraries (TestBeamIntersectionVTK ${TEST_LIBS}) - - add_executable (TestGateValveDiscretization - ${CMAKE_CURRENT_SOURCE_DIR}/TestGateValveDiscretization.cc) - target_link_libraries (TestGateValveDiscretization ${TEST_LIBS}) - - add_executable (TestGateValveIntersectionVTK - ${CMAKE_CURRENT_SOURCE_DIR}/TestGateValveIntersectionVTK.cc) - target_link_libraries (TestGateValveIntersectionVTK ${TEST_LIBS}) - - add_executable (TestPortHousingDiscretization - ${CMAKE_CURRENT_SOURCE_DIR}/TestPortHousingDiscretization.cc) - target_link_libraries (TestPortHousingDiscretization ${TEST_LIBS}) - - add_executable (TestPortHousingIntersectionVTK - ${CMAKE_CURRENT_SOURCE_DIR}/TestPortHousingIntersectionVTK.cc) - target_link_libraries (TestPortHousingIntersectionVTK ${TEST_LIBS}) - - add_executable (TestRodDiscretization - ${CMAKE_CURRENT_SOURCE_DIR}/TestRodDiscretization.cc) - target_link_libraries (TestRodDiscretization ${TEST_LIBS}) - - add_executable (TestRodIntersectionVTK - ${CMAKE_CURRENT_SOURCE_DIR}/TestRodIntersectionVTK.cc) - target_link_libraries (TestRodIntersectionVTK ${TEST_LIBS}) - - - add_executable (TestRotatedSurfaceDiscretization - ${CMAKE_CURRENT_SOURCE_DIR}/TestRotatedSurfaceDiscretization.cc) - target_link_libraries (TestRotatedSurfaceDiscretization ${TEST_LIBS}) - - add_executable (TestWireArrayDiscretization - ${CMAKE_CURRENT_SOURCE_DIR}/TestWireArrayDiscretization.cc) - target_link_libraries (TestWireArrayDiscretization ${TEST_LIBS}) - -# add_executable (TestTorusIntersection -# ${CMAKE_CURRENT_SOURCE_DIR}/TestTorusIntersection.cc) -# target_link_libraries (TestTorusIntersection ${TEST_LIBS}) - - add_executable (TestRotatedSurfaceIntersectionVTK - ${CMAKE_CURRENT_SOURCE_DIR}/TestRotatedSurfaceIntersectionVTK.cc) - target_link_libraries (TestRotatedSurfaceIntersectionVTK ${TEST_LIBS}) - -# add_executable (TestCutConeShellIntersection -# ${CMAKE_CURRENT_SOURCE_DIR}/TestCutConeShellIntersection.cc) -# target_link_libraries (TestCutConeShellIntersection ${TEST_LIBS}) - -# add_executable (TestTriangleIntersection -# ${CMAKE_CURRENT_SOURCE_DIR}/TestTriangleIntersection.cc) -# target_link_libraries (TestTriangleIntersection ${TEST_LIBS}) - -# add_executable (TestBeamIntersection -# ${CMAKE_CURRENT_SOURCE_DIR}/TestBeamIntersection.cc) -# target_link_libraries (TestBeamIntersection ${TEST_LIBS}) - - add_executable (TestWireArrayIntersectionVTK - ${CMAKE_CURRENT_SOURCE_DIR}/TestWireArrayIntersectionVTK.cc) - target_link_libraries (TestWireArrayIntersectionVTK ${TEST_LIBS}) - - add_executable (TestWireIntersectionVTK - ${CMAKE_CURRENT_SOURCE_DIR}/TestWireIntersectionVTK.cc) - target_link_libraries (TestWireIntersectionVTK ${TEST_LIBS}) - - -add_executable (TestDiscretization -${CMAKE_CURRENT_SOURCE_DIR}/TestDiscretization.cc) -target_link_libraries (TestDiscretization ${TEST_LIBS}) - -add_executable (TestMeshTags -${CMAKE_CURRENT_SOURCE_DIR}/TestMeshTags.cc) -target_link_libraries (TestMeshTags ${TEST_LIBS}) - -add_executable (TestNesting -${CMAKE_CURRENT_SOURCE_DIR}/TestNesting.cc) -target_link_libraries (TestNesting ${TEST_LIBS}) - -add_executable (TestRepeatedShapes -${CMAKE_CURRENT_SOURCE_DIR}/TestRepeatedShapes.cc) -target_link_libraries (TestRepeatedShapes ${TEST_LIBS}) - -add_executable (TestVisualization -${CMAKE_CURRENT_SOURCE_DIR}/TestVisualization.cc) -target_link_libraries (TestVisualization ${TEST_LIBS}) - -add_executable (TestKGDetectorRegion -${CMAKE_CURRENT_SOURCE_DIR}/TestKGDetectorRegion.cc) -target_link_libraries (TestKGDetectorRegion ${TEST_LIBS}) - -add_executable (TestKGMainSpectrometer -${CMAKE_CURRENT_SOURCE_DIR}/TestKGMainSpectrometer.cc) -target_link_libraries (TestKGMainSpectrometer ${TEST_LIBS}) - -add_executable (TestKGPumpPortRods -${CMAKE_CURRENT_SOURCE_DIR}/TestKGPumpPortRods.cc) -target_link_libraries (TestKGPumpPortRods ${TEST_LIBS}) - -add_executable (TestKGWireModule -${CMAKE_CURRENT_SOURCE_DIR}/TestKGWireModule.cc) -target_link_libraries (TestKGWireModule ${TEST_LIBS}) - -add_executable (TestGateValve -${CMAKE_CURRENT_SOURCE_DIR}/TestGateValve.cc) -target_link_libraries (TestGateValve ${TEST_LIBS}) - -add_executable (TestKGWireModuleRing -${CMAKE_CURRENT_SOURCE_DIR}/TestKGWireModuleRing.cc) -target_link_libraries (TestKGWireModuleRing ${TEST_LIBS}) - -kasper_install_executables ( - Test2DPolygon - Test2DPolygonWithArcs - Test2DArc - Test2DLineSegment - TestPolygonWithArcs3d - TestBeamDiscretization - TestBeamIntersectionVTK - TestConicSectPortHousingDiscretization - TestConicSectPortHousingIntersectionVTK - TestExtrudedSurfaceDiscretization - TestExtrudedSurfaceIntersectionVTK - TestGateValveDiscretization - TestGateValveIntersectionVTK - TestPortHousingDiscretization - TestPortHousingIntersectionVTK - TestRotatedSurfaceDiscretization - TestRodDiscretization - TestRodIntersectionVTK - TestWireArrayDiscretization -# TestTorusIntersection - TestRotatedSurfaceIntersectionVTK -# TestCutConeShellIntersection -# TestTriangleIntersection -# TestBeamIntersection - TestWireArrayIntersectionVTK - TestWireIntersectionVTK - TestDiscretization - TestMeshTags - TestNesting - TestRepeatedShapes - TestVisualization - TestKGDetectorRegion - TestKGMainSpectrometer - TestKGPumpPortRods - TestKGWireModule - TestKGWireModuleRing - TestGateValve -) diff --git a/KGeoBag/Source/Test/MeshNavigation/CMakeLists.txt b/KGeoBag/Source/Test/MeshNavigation/CMakeLists.txt index a9fe36af2..140fc40b6 100644 --- a/KGeoBag/Source/Test/MeshNavigation/CMakeLists.txt +++ b/KGeoBag/Source/Test/MeshNavigation/CMakeLists.txt @@ -1,51 +1,27 @@ if(KGeoBag_USE_VTK) -set (TESTMESHNAVIGATION_LIBS - ${Kommon_LIBRARIES} - ${Kommon_Vtk_LIBRARIES} - KGeoBagMath - KGeoBagCore - KGeoBagShapes - KGeoBagAppearance - KGeoBagMesh - KGeoBagAxialMesh - KGeoBagBindings - KGeoBagRandom - KGeoBagMetrics - KGeoBagBasicVisualization - KGeoBagVtkVisualization -) - -# internal -kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Math/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Core/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Shapes/Complex/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Shapes/PlanarShapes/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Shapes/FlattenedAreas/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Shapes/RotatedAreas/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Shapes/RotatedVolumes/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Shapes/ExtrudedAreas/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Shapes/ExtrudedVolumes/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Shapes/ShellAreas/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Extensions/Appearance/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Extensions/Deformation/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Extensions/Mesh/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Extensions/Mesh/Navigation/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Extensions/AxialMesh/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Extensions/DiscreteRotationalMesh/Include - ${CMAKE_CURRENT_SOURCE_DIR}/Visualization/Include -) - - - - -add_executable (TestMeshNavigation -${CMAKE_CURRENT_SOURCE_DIR}/TestMeshNavigation.cc) -target_link_libraries (TestMeshNavigation ${TESTMESHNAVIGATION_LIBS}) - -kasper_install_executables ( - TestMeshNavigation -) + set (TESTMESHNAVIGATION_LIBS + Kommon + KommonVtk + KGeoBagMath + KGeoBagCore + KGeoBagShapes + KGeoBagAppearance + KGeoBagMesh + KGeoBagAxialMesh + KGeoBagBindings + KGeoBagRandom + KGeoBagMetrics + KGeoBagBasicVisualization + KGeoBagVtkVisualization + ) + + add_executable (TestMeshNavigation + ${CMAKE_CURRENT_SOURCE_DIR}/TestMeshNavigation.cc) + target_link_libraries (TestMeshNavigation ${TESTMESHNAVIGATION_LIBS}) + + kasper_install_executables ( + TestMeshNavigation + ) endif(KGeoBag_USE_VTK) diff --git a/KGeoBag/Source/Visualization/CMakeLists.txt b/KGeoBag/Source/Visualization/CMakeLists.txt index b1929dcda..2b7814317 100644 --- a/KGeoBag/Source/Visualization/CMakeLists.txt +++ b/KGeoBag/Source/Visualization/CMakeLists.txt @@ -1,4 +1,5 @@ #basic visual + # headers set( BASIC_VISUALIZATION_HEADER_FILES Basic/Include/KGVisualizationMessage.hh @@ -11,127 +12,113 @@ set( BASIC_VISUALIZATION_SOURCE_FILES Basic/Source/KGGeometryPrinter.cc ) - -# internal -kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Basic/Include -) - # target -add_library( KGeoBagBasicVisualization SHARED ${BASIC_VISUALIZATION_SOURCE_FILES} ${BASIC_VISUALIZATION_HEADER_FILES} ) +add_library( KGeoBagBasicVisualization + SHARED ${BASIC_VISUALIZATION_SOURCE_FILES} ${BASIC_VISUALIZATION_HEADER_FILES} +) +target_include_directories( KGeoBagBasicVisualization + PUBLIC $ $ +) target_link_libraries( KGeoBagBasicVisualization - ${Kommon_LIBRARIES} - KGeoBagCore - KGeoBagShapes - KGeoBagAppearance - KGeoBagMesh - KGeoBagAxialMesh + PUBLIC + KGeoBagAppearance + KGeoBagMesh + KGeoBagAxialMesh ) + # install kasper_install_headers( ${BASIC_VISUALIZATION_HEADER_FILES} ) kasper_install_libraries( KGeoBagBasicVisualization ) +####### +# VTK # +####### -#VTK Stuff if( KGeoBag_USE_VTK ) - - # headers - set( VTK_VISUALIZATION_HEADER_FILES - Vtk/Include/KGVTKGeometryPainter.hh - Vtk/Include/KGVTKMeshPainter.hh - Vtk/Include/KGVTKAxialMeshPainter.hh - Vtk/Include/KGVTKPointTester.hh - Vtk/Include/KGVTKNormalTester.hh - Vtk/Include/KGVTKDistanceTester.hh - Vtk/Include/KGVTKOutsideTester.hh - Vtk/Include/KGVTKRandomPointTester.hh - Vtk/Include/KGVTKMeshIntersectionTester.hh - ) - - # source - set( VTK_VISUALIZATION_SOURCE_FILES - Vtk/Source/KGVTKGeometryPainter.cc - Vtk/Source/KGVTKMeshPainter.cc - Vtk/Source/KGVTKAxialMeshPainter.cc - Vtk/Source/KGVTKPointTester.cc - Vtk/Source/KGVTKNormalTester.cc - Vtk/Source/KGVTKDistanceTester.cc - Vtk/Source/KGVTKOutsideTester.cc - Vtk/Source/KGVTKRandomPointTester.cc - Vtk/Source/KGVTKMeshIntersectionTester.cc - ) - - # external - kasper_find_vtk() - if( VTK_MAJOR_VERSION GREATER 5 ) - set_property( SOURCE ${VTK_VISUALIZATION_SOURCE_FILES} ${VTK_VISUALIZATION_HEADER_FILES} APPEND PROPERTY COMPILE_DEFINITIONS VTK6 ) - endif() - - # internal - kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Vtk/Include - ) - - # target - add_library( KGeoBagVtkVisualization SHARED ${VTK_VISUALIZATION_SOURCE_FILES} ${VTK_VISUALIZATION_HEADER_FILES} ) - target_link_libraries( KGeoBagVtkVisualization - KGeoBagBasicVisualization - KGeoBagCore - KGeoBagShapes - KGeoBagAppearance - KGeoBagMesh - KGeoBagAxialMesh - ${Kommon_LIBRARIES} - ${Kommon_Vtk_LIBRARIES} - ${VTK_LIBRARIES} - ) - - # install - kasper_install_headers( ${VTK_VISUALIZATION_HEADER_FILES} ) - kasper_install_libraries( KGeoBagVtkVisualization ) + # headers + set( VTK_VISUALIZATION_HEADER_FILES + Vtk/Include/KGVTKGeometryPainter.hh + Vtk/Include/KGVTKMeshPainter.hh + Vtk/Include/KGVTKAxialMeshPainter.hh + Vtk/Include/KGVTKPointTester.hh + Vtk/Include/KGVTKNormalTester.hh + Vtk/Include/KGVTKDistanceTester.hh + Vtk/Include/KGVTKOutsideTester.hh + Vtk/Include/KGVTKRandomPointTester.hh + Vtk/Include/KGVTKMeshIntersectionTester.hh + ) + + # source + set( VTK_VISUALIZATION_SOURCE_FILES + Vtk/Source/KGVTKGeometryPainter.cc + Vtk/Source/KGVTKMeshPainter.cc + Vtk/Source/KGVTKAxialMeshPainter.cc + Vtk/Source/KGVTKPointTester.cc + Vtk/Source/KGVTKNormalTester.cc + Vtk/Source/KGVTKDistanceTester.cc + Vtk/Source/KGVTKOutsideTester.cc + Vtk/Source/KGVTKRandomPointTester.cc + Vtk/Source/KGVTKMeshIntersectionTester.cc + ) + + # target + add_library( KGeoBagVtkVisualization SHARED + ${VTK_VISUALIZATION_SOURCE_FILES} ${VTK_VISUALIZATION_HEADER_FILES} + ) + target_include_directories( KGeoBagVtkVisualization + PUBLIC $ $ + ) + target_link_libraries( KGeoBagVtkVisualization + PUBLIC + KommonVtk + KGeoBagBasicVisualization + ) + + target_compile_definitions( KGeoBagVtkVisualization PUBLIC KGeoBag_USE_VTK ) + if( VTK_MAJOR_VERSION GREATER 5 ) + target_compile_definitions( KGeoBagVtkVisualization PRIVATE VTK6 ) + endif() + + # install + kasper_install_headers( ${VTK_VISUALIZATION_HEADER_FILES} ) + kasper_install_libraries( KGeoBagVtkVisualization ) endif( KGeoBag_USE_VTK ) -#ROOT Stuff +######## +# ROOT # +######## + if( KGeoBag_USE_ROOT ) - # headers - set( ROOT_VISUALIZATION_HEADER_FILES - Root/Include/KGROOTGeometryPainter.hh - ) - - # source - set( ROOT_VISUALIZATION_SOURCE_FILES - Root/Source/KGROOTGeometryPainter.cc - ) - - # external -# find_package( ROOT 5.24.0 REQUIRED ) - kasper_external_include_directories( - ${ROOT_INCLUDE_DIR} - ) - - # internal - kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Root/Include - ) - - # target - add_library( KGeoBagROOTVisualization SHARED ${ROOT_VISUALIZATION_SOURCE_FILES} ${ROOT_VISUALIZATION_HEADER_FILES} ) - target_link_libraries( KGeoBagROOTVisualization - ${ROOT_LIBRARIES} - ${Kommon_LIBRARIES} - KGeoBagBasicVisualization - KGeoBagCore - KGeoBagShapes - KGeoBagAppearance - KGeoBagMesh - KGeoBagAxialMesh - ) - - # install - kasper_install_headers( ${ROOT_VISUALIZATION_HEADER_FILES} ) - kasper_install_libraries( KGeoBagROOTVisualization ) + # headers + set( ROOT_VISUALIZATION_HEADER_FILES + Root/Include/KGROOTGeometryPainter.hh + ) + + # source + set( ROOT_VISUALIZATION_SOURCE_FILES + Root/Source/KGROOTGeometryPainter.cc + ) + + # target + add_library( KGeoBagROOTVisualization SHARED + ${ROOT_VISUALIZATION_SOURCE_FILES} ${ROOT_VISUALIZATION_HEADER_FILES} + ) + target_include_directories( KGeoBagROOTVisualization + PUBLIC $ $ + ) + target_link_libraries( KGeoBagROOTVisualization + PUBLIC + KGeoBagBasicVisualization + ROOT::Core + ) + + target_compile_definitions( KGeoBagROOTVisualization PUBLIC KGeoBag_USE_ROOT ) + + # install + kasper_install_headers( ${ROOT_VISUALIZATION_HEADER_FILES} ) + kasper_install_libraries( KGeoBagROOTVisualization ) endif( KGeoBag_USE_ROOT ) diff --git a/KGeoBag/Source/Visualization/Root/Include/KGROOTGeometryPainter.hh b/KGeoBag/Source/Visualization/Root/Include/KGROOTGeometryPainter.hh index 446ec08ed..d01db3e95 100644 --- a/KGeoBag/Source/Visualization/Root/Include/KGROOTGeometryPainter.hh +++ b/KGeoBag/Source/Visualization/Root/Include/KGROOTGeometryPainter.hh @@ -42,6 +42,7 @@ //include root stuff #include "KField.h" #include "TPolyLine.h" +#include "TText.h" #include #include @@ -107,6 +108,10 @@ class KGROOTGeometryPainter : double GetYMin() override; double GetYMax() override; + K_SET(bool, ShowLabels); + K_SET(bool, SaveJSON); + K_SET(bool, SaveSVG); + private: std::vector fSurfaces; std::vector fSpaces; @@ -436,6 +441,7 @@ class KGROOTGeometryPainter : //rendering functions //******************* + void PolyLineToROOTLabel(const TPolyLine* aPolyLine); void OrderedPointsToROOTSurface(const OrderedPoints& anOrderedPoints); void OrderedPointsToROOTSpace(const OrderedPoints& anOrderedPoints); @@ -444,10 +450,12 @@ class KGROOTGeometryPainter : //root stuff std::vector fROOTSpaces; std::vector fROOTSurfaces; + std::vector fROOTLabels; KGSpace* fCurrentSpace; KGSurface* fCurrentSurface; KGAppearanceData* fCurrentData; + katrin::KTagSet fCurrentTags; KGeoBag::KThreeVector fCurrentOrigin; KGeoBag::KThreeVector fCurrentXAxis; KGeoBag::KThreeVector fCurrentYAxis; diff --git a/KGeoBag/Source/Visualization/Root/Source/KGROOTGeometryPainter.cc b/KGeoBag/Source/Visualization/Root/Source/KGROOTGeometryPainter.cc index 4eeb94c7a..e33eff8c4 100644 --- a/KGeoBag/Source/Visualization/Root/Source/KGROOTGeometryPainter.cc +++ b/KGeoBag/Source/Visualization/Root/Source/KGROOTGeometryPainter.cc @@ -3,6 +3,7 @@ #include "KConst.h" #include "KFile.h" #include "KGVisualizationMessage.hh" +#include "KStringUtils.h" #include #include @@ -16,6 +17,9 @@ namespace KGeoBag { KGROOTGeometryPainter::KGROOTGeometryPainter() : + fShowLabels(false), + fSaveJSON(false), + fSaveSVG(false), fPlaneNormal(0.0, 1.0, 0.0), fPlanePoint(0.0, 0.0, 0.0), fSwapAxis(false), @@ -35,16 +39,26 @@ KGROOTGeometryPainter::KGROOTGeometryPainter() : {} KGROOTGeometryPainter::~KGROOTGeometryPainter() { - for (auto& space : fROOTSpaces) { + for (auto& space : fROOTSpaces) delete space; - } - for (auto& surface : fROOTSurfaces) { + for (auto& surface : fROOTSurfaces) delete surface; - } + for (auto& label : fROOTLabels) + delete label; } void KGROOTGeometryPainter::Render() { + for (auto& space : fROOTSpaces) + delete space; + for (auto& surface : fROOTSurfaces) + delete surface; + for (auto& label : fROOTLabels) + delete label; + fROOTSpaces.clear(); + fROOTSurfaces.clear(); + fROOTLabels.clear(); + CalculatePlaneCoordinateSystem(); KGSurface* tSurface; @@ -234,6 +248,35 @@ void KGROOTGeometryPainter::Display() surface->SetLineWidth(1); surface->Draw(); } + + if (fShowLabels) { + vismsg(eInfo) << "ROOT geometry painter drawing " << fROOTLabels.size() << " labels" << eom; + + vector tBBoxes; + + for (auto& label : fROOTLabels) { + label->SetTextAlign(22); // centered + label->SetTextFont(423); // helvetica-medium-r-normal / scalabale+rotatable + label->SetTextSizePixels(12); + label->SetTextColorAlpha(kBlue + 2, 0.2); + + // avoid (some) text overlaps - this is far from perfect! + for (auto & otherBox : tBBoxes) { + auto thisBox = label->GetBBox(); + int dir = 1; + while (thisBox.fX >= otherBox.fX && thisBox.fX+thisBox.fWidth <= otherBox.fX+otherBox.fWidth && + thisBox.fY >= otherBox.fY && thisBox.fY+thisBox.fHeight <= otherBox.fY+otherBox.fHeight) { + label->SetX(label->GetX() + dir*0.01); + label->SetY(label->GetY() + dir*0.01); + thisBox = label->GetBBox(); + dir *= -1; + } + } + + label->Draw(); + tBBoxes.push_back(label->GetBBox()); + } + } } Write(); // FIXME @@ -246,8 +289,11 @@ void KGROOTGeometryPainter::Write() //if (fWriteEnabled == true) { - WriteJSON(); - WriteSVG(); + if (fSaveJSON) + WriteJSON(); + + if (fSaveSVG) + WriteSVG(); //} return; @@ -498,6 +544,7 @@ void KGROOTGeometryPainter::VisitSurface(KGSurface* aSurface) fCurrentXAxis = aSurface->GetXAxis(); fCurrentYAxis = aSurface->GetYAxis(); fCurrentZAxis = aSurface->GetZAxis(); + fCurrentTags = aSurface->GetTags(); if (aSurface->HasExtension() == true) { fCurrentData = aSurface->AsExtension(); @@ -1135,6 +1182,7 @@ void KGROOTGeometryPainter::VisitSpace(KGSpace* aSpace) fCurrentXAxis = aSpace->GetXAxis(); fCurrentYAxis = aSpace->GetYAxis(); fCurrentZAxis = aSpace->GetZAxis(); + fCurrentTags = aSpace->GetTags(); if (aSpace->HasExtension() == true) { fCurrentData = aSpace->AsExtension(); @@ -3574,6 +3622,29 @@ void KGROOTGeometryPainter::CombineOrderedPoints(OrderedPoints& anOrderedPoints) //rendering functions //******************* +void KGROOTGeometryPainter::PolyLineToROOTLabel(const TPolyLine* aPolyLine) +{ + int tNumPoints = aPolyLine->Size(); + double tMidX = 0, tMidY = 0; + + // get midpoint + for (Int_t i = 0; i < tNumPoints; i++) { + tMidX += aPolyLine->GetX()[i]; + tMidY += aPolyLine->GetY()[i]; + } + tMidX /= (double) tNumPoints; + tMidY /= (double) tNumPoints; + + // get label string + stringstream ss; + for (auto & tag : fCurrentTags) { + ss << "@" << tag << " "; + } + + auto *tLabel = new TText(tMidX, tMidY, ss.str().c_str()); + fROOTLabels.push_back(tLabel); +} + void KGROOTGeometryPainter::OrderedPointsToROOTSurface(const OrderedPoints& anOrderedPoints) { for (const auto& tPoints : anOrderedPoints.fData) { @@ -3592,8 +3663,10 @@ void KGROOTGeometryPainter::OrderedPointsToROOTSurface(const OrderedPoints& anOr } if (tPolyLine->Size() > 0) { fROOTSurfaces.push_back(tPolyLine); + PolyLineToROOTLabel(tPolyLine); } } + return; } @@ -3829,6 +3902,7 @@ void KGROOTGeometryPainter::OrderedPointsToROOTSpace(const OrderedPoints& anOrde } if (tPolyLine->Size() > 0) { fROOTSpaces.push_back(tPolyLine); + PolyLineToROOTLabel(tPolyLine); } } return; diff --git a/KGeoBag/Source/Visualization/Vtk/Include/KGVTKGeometryPainter.hh b/KGeoBag/Source/Visualization/Vtk/Include/KGVTKGeometryPainter.hh index 95239787d..42cf77340 100644 --- a/KGeoBag/Source/Visualization/Vtk/Include/KGVTKGeometryPainter.hh +++ b/KGeoBag/Source/Visualization/Vtk/Include/KGVTKGeometryPainter.hh @@ -30,6 +30,7 @@ #include "KGShellLineSegmentSurface.hh" #include "KGShellPolyLineSurface.hh" #include "KGShellPolyLoopSurface.hh" +#include "KGStlFileSurface.hh" #include "KVTKPainter.h" #include "KVTKWindow.h" #include "vtkActor.h" @@ -42,6 +43,7 @@ #include #include +#include namespace KGeoBag { @@ -69,6 +71,7 @@ class KGVTKGeometryPainter : public KGExtrudedPolyLoopSurface::Visitor, public KGConicalWireArraySurface::Visitor, public KGRodSurface::Visitor, + public KGStlFileSurface::Visitor, public KGSpace::Visitor, public KGRotatedLineSegmentSpace::Visitor, public KGRotatedArcSegmentSpace::Visitor, @@ -102,10 +105,14 @@ class KGVTKGeometryPainter : void AddSurface(KGSurface* aSurface); void AddSpace(KGSpace* aSpace); + std::string HelpText() override; + void OnKeyPress(vtkObject* aCaller, long unsigned int eventId, void* aClient, void* callData) override; + private: std::string fFile; std::string fPath; bool fWriteSTL; + int fPlaneMode; std::vector fSurfaces; std::vector fSpaces; @@ -137,6 +144,7 @@ class KGVTKGeometryPainter : void VisitExtrudedPathSurface(KGExtrudedPolyLoopSurface* aExtrudedPolyLoopSurface) override; void VisitWrappedSurface(KGConicalWireArraySurface* aConicalWireArraySurface) override; void VisitWrappedSurface(KGRodSurface* aRodSurface) override; + void VisitWrappedSurface(KGStlFileSurface* aStlFileSurface) override; //************** //space visitors @@ -225,6 +233,7 @@ class KGVTKGeometryPainter : class ShellMesh : public Mesh {}; + class TorusMesh : public Mesh {}; @@ -271,6 +280,7 @@ class KGVTKGeometryPainter : //rendering functions //******************* + void MeshToVTK(const Mesh& aMesh); void FlatMeshToVTK(const FlatMesh& aMesh); void TubeMeshToVTK(const TubeMesh& aMesh); void TubeMeshToVTK(const TubeMesh& aMesh, const KGeoBag::KThreeVector& anApexEnd); diff --git a/KGeoBag/Source/Visualization/Vtk/Source/KGVTKGeometryPainter.cc b/KGeoBag/Source/Visualization/Vtk/Source/KGVTKGeometryPainter.cc index ed391940d..fe9a9616b 100644 --- a/KGeoBag/Source/Visualization/Vtk/Source/KGVTKGeometryPainter.cc +++ b/KGeoBag/Source/Visualization/Vtk/Source/KGVTKGeometryPainter.cc @@ -11,12 +11,15 @@ #include "KConst.h" #include "vtkAppendPolyData.h" #include "vtkCellArray.h" +#include "vtkCutter.h" #include "vtkDepthSortPolyData.h" #include "vtkIVWriter.h" #include "vtkPolyDataMapper.h" +#include "vtkTriangle.h" #include "vtkQuad.h" +#include "vtkPlane.h" +#include "vtkPolygon.h" #include "vtkSTLWriter.h" -#include "vtkTriangle.h" #include "vtkTriangleFilter.h" #include "vtkXMLPolyDataWriter.h" @@ -30,6 +33,7 @@ namespace KGeoBag KGVTKGeometryPainter::KGVTKGeometryPainter() : fPath(""), fWriteSTL(false), + fPlaneMode(0), fPoints(vtkSmartPointer::New()), fCells(vtkSmartPointer::New()), fColors(vtkSmartPointer::New()), @@ -202,6 +206,127 @@ void KGVTKGeometryPainter::AddSpace(KGSpace* aSpace) return; } +string KGVTKGeometryPainter::HelpText() +{ + std::ostringstream tText; + + tText << " geometry painter:" << '\n'; + tText << " X,Y,Z - toggle slice mode (cut through plane with x/y/z normal)" << '\n'; + + return tText.str(); +} + +void KGVTKGeometryPainter::OnKeyPress(vtkObject* aCaller, long unsigned int /*eventId*/, void* /*aClient*/, void* /*callData*/) +{ + auto* tInteractor = static_cast(aCaller); + + string Symbol = tInteractor->GetKeySym(); + bool WithShift = tInteractor->GetShiftKey(); + bool WithCtrl = tInteractor->GetControlKey(); + + //utilmsg(eDebug) << "key press in VTK geometry painter: " << Symbol << (WithShift ? "+shift" : "") << (WithCtrl ? "+ctrl" : "") << eom; + + if ((WithShift == false) && (WithCtrl == false)) { + //screenshot + if (Symbol == string("x")) { + if (fPlaneMode != 1) { + vtkSmartPointer vPlane = vtkSmartPointer::New(); + vPlane->SetOrigin(0., 0., 0.); + vPlane->SetNormal(1., 0., 0.); + + vtkSmartPointer vCutter = vtkSmartPointer::New(); + vCutter->SetCutFunction(vPlane); + + #ifdef VTK6 + vCutter->SetInputData(fPolyData); + fMapper->SetInputConnection(vCutter->GetOutputPort()); + #else + vCutter->SetInput(fPolyData); + fMapper->SetInput(vCutter); + #endif + + vCutter->Update(); + fMapper->Update(); + fPlaneMode = 1; + } + else { + #ifdef VTK6 + fMapper->SetInputData(fPolyData); + #else + fMapper->SetInput(fPolyData); + #endif + + fMapper->Update(); + fPlaneMode = 0; + } + } + else if (Symbol == string("y")) { + if (fPlaneMode != 2) { + vtkSmartPointer vPlane = vtkSmartPointer::New(); + vPlane->SetOrigin(0., 0., 0.); + vPlane->SetNormal(0., 1., 0.); + + vtkSmartPointer vCutter = vtkSmartPointer::New(); + vCutter->SetCutFunction(vPlane); + + #ifdef VTK6 + vCutter->SetInputData(fPolyData); + fMapper->SetInputConnection(vCutter->GetOutputPort()); + #else + vCutter->SetInput(fPolyData); + fMapper->SetInput(vCutter); + #endif + + vCutter->Update(); + fMapper->Update(); + fPlaneMode = 2; + } + else { + #ifdef VTK6 + fMapper->SetInputData(fPolyData); + #else + fMapper->SetInput(fPolyData); + #endif + + fMapper->Update(); + fPlaneMode = 0; + } + } + else if (Symbol == string("z")) { + if (fPlaneMode != 3) { + vtkSmartPointer vPlane = vtkSmartPointer::New(); + vPlane->SetOrigin(0., 0., 0.); + vPlane->SetNormal(0., 0., 1.); + + vtkSmartPointer vCutter = vtkSmartPointer::New(); + vCutter->SetCutFunction(vPlane); + + #ifdef VTK6 + vCutter->SetInputData(fPolyData); + fMapper->SetInputConnection(vCutter->GetOutputPort()); + #else + vCutter->SetInput(fPolyData); + fMapper->SetInput(vCutter); + #endif + + vCutter->Update(); + fMapper->Update(); + fPlaneMode = 3; + } + else { + #ifdef VTK6 + fMapper->SetInputData(fPolyData); + #else + fMapper->SetInput(fPolyData); + #endif + + fMapper->Update(); + fPlaneMode = 0; + } + } + } +} + //**************** //surface visitors //**************** @@ -794,6 +919,26 @@ void KGVTKGeometryPainter::VisitWrappedSurface(KGRodSurface* aRodSurface) return; } +void KGVTKGeometryPainter::VisitWrappedSurface(KGStlFileSurface* aStlFileSurface) +{ + if (fIgnore == true) { + return; + } + + // create rotated points and create mesh + Mesh tMeshPoints; + for (auto & elem : aStlFileSurface->GetObject()->GetElements()) { + Mesh::Group tMeshGroup = { elem.GetP0(), elem.GetP1(), elem.GetP2() }; + tMeshPoints.fData.push_back(tMeshGroup); + } + + //create mesh + MeshToVTK(tMeshPoints); + + //clear space + fCurrentSurface = nullptr; +} + //************** //space visitors //************** @@ -1804,6 +1949,57 @@ void KGVTKGeometryPainter::ThreePointsToTubeMeshToVTK(const ThreePoints& aThreeP //rendering functions //******************* +void KGVTKGeometryPainter::MeshToVTK(const Mesh& aMesh) +{ + //object allocation + KThreeVector tPoint; + + deque vMeshIdGroup; + deque> vMeshIdSet; + + deque::iterator vThisPoint; + deque>::iterator vThisGroup; + + vtkSmartPointer vCell; + + //create mesh point ids + for (const auto& tSetIt : aMesh.fData) { + vMeshIdGroup.clear(); + for (const auto& tGroupIt : tSetIt) { + LocalToGlobal(tGroupIt, tPoint); + vMeshIdGroup.push_back(fPoints->InsertNextPoint(tPoint.X(), tPoint.Y(), tPoint.Z())); + } + vMeshIdSet.push_back(vMeshIdGroup); + } + + //create hull cells + vThisGroup = vMeshIdSet.begin(); + + while (vThisGroup != vMeshIdSet.end()) { + vThisPoint = vThisGroup->begin(); + if (vThisGroup->size() <= 2) + continue; + else if (vThisGroup->size() == 3) + vCell = vtkSmartPointer::New(); + else if (vThisGroup->size() == 4) + vCell = vtkSmartPointer::New(); + else + vCell = vtkSmartPointer::New(); + + for (unsigned i = 0; i < vThisGroup->size(); i++) + vCell->GetPointIds()->SetId(i, *(vThisPoint++)); + fCells->InsertNextCell(vCell); + fColors->InsertNextTuple4(fCurrentData->GetColor().GetRed(), + fCurrentData->GetColor().GetGreen(), + fCurrentData->GetColor().GetBlue(), + fCurrentData->GetColor().GetOpacity()); + + ++vThisGroup; + } + + return; +} + void KGVTKGeometryPainter::FlatMeshToVTK(const FlatMesh& aMesh) { //object allocation diff --git a/KGeoBag/Source/XML/CMakeLists.txt b/KGeoBag/Source/XML/CMakeLists.txt index abfc15503..e49c4ec3f 100644 --- a/KGeoBag/Source/XML/CMakeLists.txt +++ b/KGeoBag/Source/XML/CMakeLists.txt @@ -1,11 +1,15 @@ # examples kasper_install_config_subdir( Examples ${CMAKE_CURRENT_SOURCE_DIR}/Examples/ComplexShapes.xml ) kasper_install_config_subdir( Examples ${CMAKE_CURRENT_SOURCE_DIR}/Examples/SimpleShapes.xml ) +kasper_install_config_subdir( Examples ${CMAKE_CURRENT_SOURCE_DIR}/Examples/ExternalShapes.xml ) kasper_install_config_subdir( Scripts ${CMAKE_CURRENT_SOURCE_DIR}/Scripts/PaintGeometry.xml ) kasper_install_config_subdir( Scripts ${CMAKE_CURRENT_SOURCE_DIR}/Scripts/PaintMesh.xml ) kasper_install_config_subdir( Scripts ${CMAKE_CURRENT_SOURCE_DIR}/Scripts/PaintAxialMesh.xml ) kasper_install_config_subdir( Scripts ${CMAKE_CURRENT_SOURCE_DIR}/Scripts/TestDistance.xml ) kasper_install_config_subdir( Scripts ${CMAKE_CURRENT_SOURCE_DIR}/Scripts/TestOutside.xml ) -kasper_install_config_subdir( Scripts ${CMAKE_CURRENT_SOURCE_DIR}/Scripts/TestPoint.xml ) -kasper_install_config_subdir( Scripts ${CMAKE_CURRENT_SOURCE_DIR}/Scripts/TestNormal.xml ) \ No newline at end of file +kasper_install_config_subdir( Scripts ${CMAKE_CURRENT_SOURCE_DIR}/Scripts/TestPoint.xml ) +kasper_install_config_subdir( Scripts ${CMAKE_CURRENT_SOURCE_DIR}/Scripts/TestNormal.xml ) + +kasper_install_data( "${CMAKE_CURRENT_SOURCE_DIR}/DataFiles/Menger_sponge.stl" ) +kasper_install_data( "${CMAKE_CURRENT_SOURCE_DIR}/DataFiles/Utah_teapot.stl" ) diff --git a/KGeoBag/Source/XML/DataFiles/Menger_sponge.stl b/KGeoBag/Source/XML/DataFiles/Menger_sponge.stl new file mode 100644 index 000000000..dfebb0a31 Binary files /dev/null and b/KGeoBag/Source/XML/DataFiles/Menger_sponge.stl differ diff --git a/KGeoBag/Source/XML/DataFiles/Utah_teapot.stl b/KGeoBag/Source/XML/DataFiles/Utah_teapot.stl new file mode 100644 index 000000000..d2259187e Binary files /dev/null and b/KGeoBag/Source/XML/DataFiles/Utah_teapot.stl differ diff --git a/KGeoBag/Source/XML/Examples/ComplexShapes.xml b/KGeoBag/Source/XML/Examples/ComplexShapes.xml index 6be4691df..a8d820dcf 100644 --- a/KGeoBag/Source/XML/Examples/ComplexShapes.xml +++ b/KGeoBag/Source/XML/Examples/ComplexShapes.xml @@ -73,7 +73,7 @@ - + diff --git a/KGeoBag/Source/XML/Examples/ExternalShapes.xml b/KGeoBag/Source/XML/Examples/ExternalShapes.xml new file mode 100644 index 000000000..f318fe4e2 --- /dev/null +++ b/KGeoBag/Source/XML/Examples/ExternalShapes.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/Kassiopeia/AnalysisExamples/QuadrupoleTrapAnalysis.ipynb b/Kassiopeia/AnalysisExamples/QuadrupoleTrapAnalysis.ipynb new file mode 100644 index 000000000..4201816ba --- /dev/null +++ b/Kassiopeia/AnalysisExamples/QuadrupoleTrapAnalysis.ipynb @@ -0,0 +1,2883 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# QuadrupoleTrapAnalysis\n", + "\n", + "This Notebook works with the `QuadrupoleTrapSimulation.xml` file located in `${KASPERSYS}/config/Kassiopeia/Examples`. The file contains a model of an quadrupole trap with three electrodes embedded in a magnetic coil." + ] + }, + { + "attachments": { + "QuadrupoleTrapSimulation.png": { + "image/png": "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XI/GnpITqvhMBIpSxhTtBECwe319/cCBA67rCiE45/SZeG7xmVQ8twJ70W+V4jM9VqfTUUpxznu9HrnkGo0G5zzLsjd+58SdO51OsZ7MlXgrdDsgV6lSpUr9vOit+c1bqlSpUj+DiuOYrjT2WnjrVXZylXrj2g/22g68aMseqIuhUcF6G55AP0HNGefRptuXMIVCroe3toCPpofUYbn0i8tIx3GnTRlBEERRGEURES5KNpEzgq6fKaZHJMjzPLqipun1dLHtOiyOkKTa9wQVz3POPI81GjKOdZ4bLlgU5XGcS8kyZYpy+m43s20+HCjH5QxsNMwdhzOwcJT7gSAPVxznlsWJZxHSKrbQnWxHXcaMX1xyXdm2LaWM49h13TiONzc7lmUDSNPUtm0qHZ+mXUopol15nhcxLpq9SOXoYRi22xsAhBDkdPN9n/rOKepIEGSac2mttV3FxJnVjcanGFNurOakpWtLRnWUwrfGK/sJGNu5sq0ZyMupBjQAW8KzoTSiFK6FioteiAIjDGMkGRxrTLssAW0hSmFLTKGGMedyLDCGigsDZPmYhXVDVFwA4478wszFGDwH671xLFrq3uFDBz0/IBRIoDAIgkceeeTkyZNKqdOnT99zzz1SysFgcPnyZeIXhw8fbjabAGq12traWrVavffeey9duuT7/vr6+unTp++///719XXbtpvN5pEjR5aXly9fvsw5L9JwrVar3W73er25uTl6iy4tLe2Tc22HVsVex3GIe3rXDkyU2zxfAOgHZAt/CYJgNBoRtOKc0wTJQgDUlAjoDIdD6p965ZVXZmZmlpeXvW09+mIi13UZY77vUyBXSklfEP9SSvV6PRolQRSpVquladput8n1tn8VWGrHEFyj0Si+7vf7YRhevHix0Wj4vr8furf7nQPodrvTr8D2M/KmqYRcpUqVejurhFylSpUqBQCrq6sArly5UkCu55577rvf/e7MzMznP//5XQ+9NTpw14OrF07utarUz7rkPrIvUuxQQLZr4OYmtQV7bWFe15i5ipUT1LXl6VgCjGGUjTuYMEVAcH3r1naqtUVWdEXX7rl605JRFBdxnyRJCGlR4RQAiukBEEIEQUAX9mRxsiYCoLWmq/EwVGFoKRVVKjKONADG4Lg8TQznzPV4EmvfE47LR8M8y3StbuncSIsB8DzBOKIoJwtbluXE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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![QuadrupoleTrapSimulation.png](attachment:QuadrupoleTrapSimulation.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "### Run this _Kassiopeia_ command to generate the output file:\n", + "\n", + "```\n", + "Kassiopeia ${KASPERSYS}/config/Kassiopeia/Examples/QuadrupoleTrapSimulation.xml\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Populating the interactive namespace from numpy and matplotlib\n" + ] + } + ], + "source": [ + "%pylab inline" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Setup modules\n", + "\n", + "import os\n", + "import numpy as np\n", + "import pandas as pd\n", + "try:\n", + " import uproot3 as uproot # try this if newer uproot does not work\n", + "except ModuleNotFoundError:\n", + " import uproot\n", + "import matplotlib.pyplot as plt\n", + "\n", + "WORKDIR = os.path.expandvars('$HOME/kasper.git/install/output/Kassiopeia/')\n", + "\n", + "if not os.path.exists(WORKDIR):\n", + " raise RuntimeError(f\"Workspace directory does not exist: {WORKDIR}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Open output file\n", + "\n", + "file_name = WORKDIR + 'QuadrupoleTrapSimulation.root'\n", + "if not os.path.exists(file_name):\n", + " raise RuntimeError(f\"Output file '{file_name}' does not exist. Please run the simulation first.\")\n", + "\n", + "data = uproot.open(file_name)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Method 1\n", + "\n", + "This method uses dataframes to iterate over each output track and process step data in the `component_step_cell` group. The steps that correspond to each track are selected by a boolean mask." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "extrema for track #0 \n", + "extrema for track #1 <0.000155068>\n", + "extrema for track #2 <0.000187115>\n", + "extrema for track #3 <0.237179>\n", + "extrema for track #4 <0.000142933>\n", + "extrema for track #5 <0.00011403>\n", + "extrema for track #6 <0.000433223>\n", + "extrema for track #7 \n" + ] + } + ], + "source": [ + "# Read data structures\n", + "df0 = data['TRACK_DATA'].pandas.df()\n", + "df1 = data['component_step_cell_DATA'].pandas.df()\n", + "df1p = data['component_step_cell_PRESENCE'].pandas.df()\n", + "\n", + "# Iterate over tracks and assign to step data\n", + "for track_id, first_step_index, last_step_index in zip(df0['TRACK_INDEX'], df0['FIRST_STEP_INDEX'], df0['LAST_STEP_INDEX']):\n", + "\n", + " step_mask = np.full(df1.shape[0], False)\n", + " \n", + " start_index = 0\n", + " for first_valid, valid_length in zip(df1p['INDEX'], df1p['LENGTH']):\n", + " last_valid = first_valid + valid_length - 1\n", + "\n", + " if first_valid >= first_step_index and last_valid <= last_step_index:\n", + " step_mask[start_index:start_index+valid_length] = True\n", + "\n", + " if start_index > last_step_index:\n", + " break\n", + "\n", + " start_index += valid_length\n", + " \n", + " # Select data of current track\n", + " steps_moment = df1['orbital_magnetic_moment'][step_mask]\n", + " max_moment = np.max(steps_moment)\n", + " min_moment = np.min(steps_moment)\n", + " \n", + " # Compute result\n", + " deviation = 2.0 * (max_moment - min_moment) / (max_moment + min_moment)\n", + " print(\"extrema for track #{:d} <{:g}>\".format(track_id, deviation))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Method 2\n", + "\n", + "This method uses dataframes to iterate over each output track and process step data in the `component_step_cell` group. The steps that correspond to each track are selected by the dataframe's `track_id` column. This method allows more complex data selections through the `df.query()` method." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "extrema for track #0 \n", + "extrema for track #1 <0.000155068>\n", + "extrema for track #2 <0.000187115>\n", + "extrema for track #3 <0.237179>\n", + "extrema for track #4 <0.000142933>\n", + "extrema for track #5 <0.00011403>\n", + "extrema for track #6 <0.000433223>\n", + "extrema for track #7 \n" + ] + } + ], + "source": [ + "# Read data structures\n", + "df0 = data['TRACK_DATA'].pandas.df()\n", + "df1 = data['component_step_cell_DATA'].pandas.df()\n", + "df1p = data['component_step_cell_PRESENCE'].pandas.df()\n", + "\n", + "# Extend step data for merging\n", + "df1 = df1.assign(track_id=np.nan)\n", + "\n", + "# Iterate over tracks and assign to step data\n", + "for track_id, first_step_index, last_step_index in zip(df0['TRACK_INDEX'], df0['FIRST_STEP_INDEX'], df0['LAST_STEP_INDEX']):\n", + "\n", + " start_index = 0\n", + " for first_valid, valid_length in zip(df1p['INDEX'], df1p['LENGTH']):\n", + " last_valid = first_valid + valid_length - 1\n", + "\n", + " if first_valid >= first_step_index and last_valid <= last_step_index:\n", + " df1.loc[start_index:start_index+valid_length-1, ('track_id')] = track_id\n", + "\n", + " if start_index > last_step_index:\n", + " break\n", + "\n", + " start_index += valid_length\n", + " \n", + " # Select data of current track\n", + " steps_moment = df1.query(\"track_id == @track_id\")['orbital_magnetic_moment']\n", + " max_moment = np.max(steps_moment)\n", + " min_moment = np.min(steps_moment)\n", + " \n", + " # Compute result\n", + " deviation = 2.0 * (max_moment - min_moment) / (max_moment + min_moment)\n", + " print(\"extrema for track #{:d} <{:g}>\".format(track_id, deviation))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Method 3\n", + "\n", + "This method uses dataframes to iterate over each output track and process step data in the `component_step_cell` group. The steps that correspond to each track are selected by the dataframe's `track_id` column. In contrast to method 2, here we use the `df.groupby()` method to break down the data into individual tracks." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "extrema for track #1 <0.000155068>\n", + "extrema for track #2 <0.000187115>\n", + "extrema for track #3 <0.237179>\n", + "extrema for track #4 <0.000142933>\n", + "extrema for track #5 <0.00011403>\n", + "extrema for track #6 <0.000433223>\n" + ] + } + ], + "source": [ + "# Read data structures\n", + "df0 = data['TRACK_DATA'].pandas.df()\n", + "df1 = data['component_step_cell_DATA'].pandas.df()\n", + "df1p = data['component_step_cell_PRESENCE'].pandas.df()\n", + "\n", + "# Extend step data for merging\n", + "df1 = df1.assign(track_id=np.nan)\n", + "\n", + "# Iterate over tracks and assign to step data\n", + "for track_id, first_step_index, last_step_index in zip(df0['TRACK_INDEX'], df0['FIRST_STEP_INDEX'], df0['LAST_STEP_INDEX']):\n", + "\n", + " start_index = 0\n", + " for first_valid, valid_length in zip(df1p['INDEX'], df1p['LENGTH']):\n", + " last_valid = first_valid + valid_length - 1\n", + "\n", + " if first_valid >= first_step_index and last_valid <= last_step_index:\n", + " df1.loc[start_index:start_index+valid_length-1, ('track_id')] = track_id\n", + "\n", + " if start_index > last_step_index:\n", + " break\n", + "\n", + " start_index += valid_length\n", + "\n", + "# Iterate over tracks and compute the results\n", + "for track_id, group in df1.groupby(\"track_id\"):\n", + " \n", + " # Here we can refer to each group's output fields individually\n", + " steps_moment = group.orbital_magnetic_moment\n", + " max_moment = np.max(steps_moment)\n", + " min_moment = np.min(steps_moment)\n", + "\n", + " deviation = 2.0 * (max_moment - min_moment) / (max_moment + min_moment)\n", + " print(\"extrema for track #{:d} <{:g}>\".format(int(track_id), deviation))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Method 4\n", + "\n", + "This method uses dataframes to iterate over each output track and process step data in the `component_step_cell` and `component_step_world` group. The step groups are first merged into a combined data frame, which is then joined with the track data in the `component_track_world` group. This allows to select data fields on the track and step level together. The steps that correspond to each track are selected by the dataframe's `track_id` column. Again, we use the `df.groupby()` method to break down the data into individual tracks." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "extrema for track #1 <0.000155068>, with max. magnetic field <5.88439> and initial energy <3.73829>\n", + "extrema for track #2 <0.000187115>, with max. magnetic field <5.88446> and initial energy <4.10653>\n", + "extrema for track #3 <0.237179>, with max. magnetic field <5.88452> and initial energy <4.4373>\n", + "extrema for track #4 <0.000142933>, with max. magnetic field <5.88452> and initial energy <3.71827>\n", + "extrema for track #5 <0.00011403>, with max. magnetic field <5.88452> and initial energy <3.70663>\n", + "extrema for track #6 <0.000433223>, with max. magnetic field <5.88452> and initial energy <3.71804>\n" + ] + } + ], + "source": [ + "# Read data structures\n", + "df0 = data['TRACK_DATA'].pandas.df()\n", + "df1 = data['component_track_world_DATA'].pandas.df()\n", + "df2 = data['component_step_world_DATA'].pandas.df()\n", + "df3 = data['component_step_cell_DATA'].pandas.df()\n", + "df2p = data['component_step_world_PRESENCE'].pandas.df()\n", + "df3p = data['component_step_cell_PRESENCE'].pandas.df()\n", + "\n", + "# Extend step data for merging\n", + "df1 = df1.assign(track_id=df0['TRACK_INDEX'])\n", + "df2 = df2.assign(track_id=np.nan, step_id=np.nan)\n", + "df3 = df3.assign(track_id=np.nan, step_id=np.nan)\n", + "\n", + "# Iterate over tracks and assign to step data\n", + "for track_id, first_step_index, last_step_index in zip(df0['TRACK_INDEX'], df0['FIRST_STEP_INDEX'], df0['LAST_STEP_INDEX']):\n", + "\n", + " start_index = 0\n", + " for first_valid, valid_length in zip(df2p['INDEX'], df2p['LENGTH']):\n", + " last_valid = first_valid + valid_length - 1\n", + "\n", + " if first_valid >= first_step_index and last_valid <= last_step_index:\n", + " df2.loc[start_index:start_index+valid_length-1, ('track_id')] = track_id\n", + " df2.loc[start_index:start_index+valid_length-1, ('step_id')] = np.arange(first_valid, last_valid+1)\n", + "\n", + " if first_valid > last_step_index:\n", + " break\n", + "\n", + " start_index += valid_length\n", + "\n", + " start_index = 0\n", + " for first_valid, valid_length in zip(df3p['INDEX'], df3p['LENGTH']):\n", + " last_valid = first_valid + valid_length - 1\n", + "\n", + " if first_valid >= first_step_index and last_valid <= last_step_index:\n", + " df3.loc[start_index:start_index+valid_length-1, ('track_id')] = track_id\n", + " df3.loc[start_index:start_index+valid_length-1, ('step_id')] = np.arange(first_valid, last_valid+1)\n", + "\n", + " if first_valid > last_step_index:\n", + " break\n", + "\n", + " start_index += valid_length\n", + "\n", + "# Assign indices for merging\n", + "df1.set_index('track_id')\n", + "df2.set_index(['track_id', 'step_id'])\n", + "df3.set_index(['track_id', 'step_id'])\n", + "\n", + "# Merge the step data frames (append columns)\n", + "# `inner` join: keep only steps that exist in *both* data frames\n", + "# `outer` join: keep all steps, even those that only exist in one data frame\n", + "df4 = pd.merge(df2, df3, on=('track_id','step_id'), how='outer')\n", + "df4.set_index(['track_id', 'step_id'])\n", + "\n", + "# Merge the track data frame (merge columns via common `track_id`)\n", + "df = pd.merge(df4, df1, on='track_id', how='outer')\n", + "df.set_index(['track_id', 'step_id'])\n", + "\n", + "for track_id,group in df.groupby(\"track_id\"):\n", + " \n", + " # Here we can refer to each group's output fields individually\n", + " steps_moment = group.orbital_magnetic_moment\n", + " max_moment = np.max(steps_moment)\n", + " min_moment = np.min(steps_moment)\n", + " \n", + " if np.isnan(steps_moment).all():\n", + " continue\n", + " \n", + " # We can also accees data from the other step output group\n", + " magnetic_field = group.magnetic_field_z.max()\n", + " \n", + " # ... and the track output group as well.\n", + " kinetic_energy = group.initial_kinetic_energy.mean()\n", + "\n", + " deviation = 2.0 * (max_moment - min_moment) / (max_moment + min_moment)\n", + " print(\"extrema for track #{:d} <{:g}>, with max. magnetic field <{:g}> and initial energy <{:g}>\".\\\n", + " format(int(track_id), deviation, magnetic_field, kinetic_energy))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Internally used dataframes\n", + "\n", + "The dataframes below contain all the output data and can be used for arbitary data selection and processing." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
TRACK_INDEXFIRST_STEP_INDEXLAST_STEP_INDEX
entry
0006253
11625410288
221028914271
331427225434
442543527943
552794441833
664183456652
775665360213
\n", + "
" + ], + "text/plain": [ + " TRACK_INDEX FIRST_STEP_INDEX LAST_STEP_INDEX\n", + "entry \n", + "0 0 0 6253\n", + "1 1 6254 10288\n", + "2 2 10289 14271\n", + "3 3 14272 25434\n", + "4 4 25435 27943\n", + "5 5 27944 41833\n", + "6 6 41834 56652\n", + "7 7 56653 60213" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df0" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
creator_nameterminator_nametotal_stepsnumber_of_turnsinitial_timeinitial_position_xinitial_position_yinitial_position_zinitial_momentum_xinitial_momentum_y...final_electric_field_zfinal_electric_potentialfinal_kinetic_energyfinal_polar_angle_to_zfinal_azimuthal_angle_to_xfinal_polar_angle_to_bfinal_orbital_magnetic_momentz_length_internalz_length_integraltrack_id
entry
0b'generator_uniform'b'nav_space:space_cell:enter'625410.000000e+00-0.000395-0.000195-0.002500-5.855381e-254.908563e-25...-1.305964e+034.0914213.73828747.00987280.04453147.0095045.446014e-200.0022810.0022810
1b'nav_space:space_cell:enter'b'int_scattering'403502.372876e-09-0.000394-0.000195-0.0015001.320993e-257.525925e-25...-1.032568e+034.4596104.10647744.25952491.29333344.2593165.445971e-200.0004500.0004501
2b'(anonymous)'b'int_scattering'398302.755610e-09-0.000394-0.000195-0.0011856.163079e-25-1.459890e-25...-7.001976e+024.7903814.43724833.81326465.42125533.8130073.741323e-200.0004640.0004642
3b'(anonymous)'b'nav_surface:surface_target:transmission'1116303.133419e-09-0.000394-0.000195-0.0008039.250647e-251.256951e-25...-8.746566e-095.0714063.71827252.699416149.88248452.6994166.405996e-200.0013500.0013503
4b'nav_surface:surface_target:transmission'b'int_scattering'250904.192153e-09-0.000393-0.0001930.000000-7.168421e-254.158317e-25...1.435965e+025.0597573.70662452.820479217.38233552.8204136.406466e-200.0002720.0002724
5b'(anonymous)'b'int_scattering'1389004.430148e-09-0.000394-0.0001930.0001658.284870e-25-6.236188e-25...2.646804e+015.0711823.71804995.508851328.64975495.5088581.002986e-190.0015060.0015065
6b'(anonymous)'b'nav_space:space_cell:exit'1481905.747689e-09-0.000394-0.0001930.000030-2.722809e-252.327153e-26...1.305962e+034.0912252.73809117.79928011.95899917.7998826.966847e-210.0015290.0015296
7b'nav_space:space_cell:exit'b'term_min_energy'356007.153396e-09-0.000394-0.0001940.0015002.673507e-255.662722e-26...2.170130e+032.3531160.99998330.385302191.96558230.3842946.966103e-210.0010810.0010817
\n", + "

8 rows × 45 columns

\n", + "
" + ], + "text/plain": [ + " creator_name \\\n", + "entry \n", + "0 b'generator_uniform' \n", + "1 b'nav_space:space_cell:enter' \n", + "2 b'(anonymous)' \n", + "3 b'(anonymous)' \n", + "4 b'nav_surface:surface_target:transmission' \n", + "5 b'(anonymous)' \n", + "6 b'(anonymous)' \n", + "7 b'nav_space:space_cell:exit' \n", + "\n", + " terminator_name total_steps \\\n", + "entry \n", + "0 b'nav_space:space_cell:enter' 6254 \n", + "1 b'int_scattering' 4035 \n", + "2 b'int_scattering' 3983 \n", + "3 b'nav_surface:surface_target:transmission' 11163 \n", + "4 b'int_scattering' 2509 \n", + "5 b'int_scattering' 13890 \n", + "6 b'nav_space:space_cell:exit' 14819 \n", + "7 b'term_min_energy' 3560 \n", + "\n", + " number_of_turns initial_time initial_position_x initial_position_y \\\n", + "entry \n", + "0 1 0.000000e+00 -0.000395 -0.000195 \n", + "1 0 2.372876e-09 -0.000394 -0.000195 \n", + "2 0 2.755610e-09 -0.000394 -0.000195 \n", + "3 0 3.133419e-09 -0.000394 -0.000195 \n", + "4 0 4.192153e-09 -0.000393 -0.000193 \n", + "5 0 4.430148e-09 -0.000394 -0.000193 \n", + "6 0 5.747689e-09 -0.000394 -0.000193 \n", + "7 0 7.153396e-09 -0.000394 -0.000194 \n", + "\n", + " initial_position_z initial_momentum_x initial_momentum_y ... \\\n", + "entry ... \n", + "0 -0.002500 -5.855381e-25 4.908563e-25 ... \n", + "1 -0.001500 1.320993e-25 7.525925e-25 ... \n", + "2 -0.001185 6.163079e-25 -1.459890e-25 ... \n", + "3 -0.000803 9.250647e-25 1.256951e-25 ... \n", + "4 0.000000 -7.168421e-25 4.158317e-25 ... \n", + "5 0.000165 8.284870e-25 -6.236188e-25 ... \n", + "6 0.000030 -2.722809e-25 2.327153e-26 ... \n", + "7 0.001500 2.673507e-25 5.662722e-26 ... \n", + "\n", + " final_electric_field_z final_electric_potential final_kinetic_energy \\\n", + "entry \n", + "0 -1.305964e+03 4.091421 3.738287 \n", + "1 -1.032568e+03 4.459610 4.106477 \n", + "2 -7.001976e+02 4.790381 4.437248 \n", + "3 -8.746566e-09 5.071406 3.718272 \n", + "4 1.435965e+02 5.059757 3.706624 \n", + "5 2.646804e+01 5.071182 3.718049 \n", + "6 1.305962e+03 4.091225 2.738091 \n", + "7 2.170130e+03 2.353116 0.999983 \n", + "\n", + " final_polar_angle_to_z final_azimuthal_angle_to_x \\\n", + "entry \n", + "0 47.009872 80.044531 \n", + "1 44.259524 91.293333 \n", + "2 33.813264 65.421255 \n", + "3 52.699416 149.882484 \n", + "4 52.820479 217.382335 \n", + "5 95.508851 328.649754 \n", + "6 17.799280 11.958999 \n", + "7 30.385302 191.965582 \n", + "\n", + " final_polar_angle_to_b final_orbital_magnetic_moment \\\n", + "entry \n", + "0 47.009504 5.446014e-20 \n", + "1 44.259316 5.445971e-20 \n", + "2 33.813007 3.741323e-20 \n", + "3 52.699416 6.405996e-20 \n", + "4 52.820413 6.406466e-20 \n", + "5 95.508858 1.002986e-19 \n", + "6 17.799882 6.966847e-21 \n", + "7 30.384294 6.966103e-21 \n", + "\n", + " z_length_internal z_length_integral track_id \n", + "entry \n", + "0 0.002281 0.002281 0 \n", + "1 0.000450 0.000450 1 \n", + "2 0.000464 0.000464 2 \n", + "3 0.001350 0.001350 3 \n", + "4 0.000272 0.000272 4 \n", + "5 0.001506 0.001506 5 \n", + "6 0.001529 0.001529 6 \n", + "7 0.001081 0.001081 7 \n", + "\n", + "[8 rows x 45 columns]" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df1" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
step_idcontinuous_timecontinuous_lengthnumber_of_turnstimeposition_xposition_yposition_zmomentum_xmomentum_ymomentum_zmagnetic_field_xmagnetic_field_ymagnetic_field_zelectric_field_xelectric_field_yelectric_field_zelectric_potentialkinetic_energytrack_id
entry
00.03.794667e-133.182840e-0703.794667e-13-0.000395-0.000194-0.002500-7.288185e-252.294092e-251.363769e-280.0000960.0000475.883916174.26678085.749975-2170.1789712.3531682.0000350.0
11.03.794667e-133.182876e-0707.589334e-13-0.000395-0.000194-0.002500-7.611409e-25-6.696744e-262.712237e-280.0000960.0000475.883916174.40194585.733130-2170.1728122.3532202.0000870.0
22.03.794667e-133.182921e-0701.138400e-12-0.000396-0.000194-0.002500-6.775845e-25-3.531530e-254.040963e-280.0000960.0000475.883916174.53174985.770216-2170.1655902.3532812.0001480.0
33.03.794667e-133.182970e-0701.517867e-12-0.000396-0.000195-0.002500-4.908700e-25-5.855783e-255.348512e-280.0000960.0000475.883916174.63642985.855583-2170.1583882.3533412.0002090.0
44.03.794667e-133.183015e-0701.897334e-12-0.000396-0.000195-0.002500-2.294229e-25-7.288588e-256.636673e-280.0000960.0000475.883916174.70005085.976234-2170.1522762.3533922.0002600.0
...............................................................
6020960209.03.794659e-132.252191e-0708.503115e-09-0.000394-0.0001930.002499-1.546179e-252.252927e-254.664605e-25-0.000096-0.0000475.883917173.75693285.3212182169.6297842.3543391.0012057.0
6021060210.03.794659e-132.251720e-0708.503494e-09-0.000394-0.0001930.002500-2.290754e-251.489691e-254.663268e-25-0.000096-0.0000475.883916173.79611885.2880872169.7975042.3539251.0007917.0
6021160211.03.794660e-132.251258e-0708.503874e-09-0.000394-0.0001930.002500-2.686573e-254.996172e-264.661934e-25-0.000096-0.0000475.883916173.84542785.2710332169.9643122.3535181.0003847.0
6021260212.03.794660e-132.250804e-0708.504253e-09-0.000394-0.0001930.002500-2.673378e-25-5.665659e-264.660607e-25-0.000096-0.0000475.883916173.89795585.2729492170.1304692.3531160.9999837.0
6021360213.00.000000e+000.000000e+0008.504253e-09-0.000394-0.0001930.002500-2.673378e-25-5.665659e-264.660607e-25-0.000096-0.0000475.883916173.89795585.2729492170.1304692.3531160.9999837.0
\n", + "

60214 rows × 20 columns

\n", + "
" + ], + "text/plain": [ + " step_id continuous_time continuous_length number_of_turns \\\n", + "entry \n", + "0 0.0 3.794667e-13 3.182840e-07 0 \n", + "1 1.0 3.794667e-13 3.182876e-07 0 \n", + "2 2.0 3.794667e-13 3.182921e-07 0 \n", + "3 3.0 3.794667e-13 3.182970e-07 0 \n", + "4 4.0 3.794667e-13 3.183015e-07 0 \n", + "... ... ... ... ... \n", + "60209 60209.0 3.794659e-13 2.252191e-07 0 \n", + "60210 60210.0 3.794659e-13 2.251720e-07 0 \n", + "60211 60211.0 3.794660e-13 2.251258e-07 0 \n", + "60212 60212.0 3.794660e-13 2.250804e-07 0 \n", + "60213 60213.0 0.000000e+00 0.000000e+00 0 \n", + "\n", + " time position_x position_y position_z momentum_x \\\n", + "entry \n", + "0 3.794667e-13 -0.000395 -0.000194 -0.002500 -7.288185e-25 \n", + "1 7.589334e-13 -0.000395 -0.000194 -0.002500 -7.611409e-25 \n", + "2 1.138400e-12 -0.000396 -0.000194 -0.002500 -6.775845e-25 \n", + "3 1.517867e-12 -0.000396 -0.000195 -0.002500 -4.908700e-25 \n", + "4 1.897334e-12 -0.000396 -0.000195 -0.002500 -2.294229e-25 \n", + "... ... ... ... ... ... \n", + "60209 8.503115e-09 -0.000394 -0.000193 0.002499 -1.546179e-25 \n", + "60210 8.503494e-09 -0.000394 -0.000193 0.002500 -2.290754e-25 \n", + "60211 8.503874e-09 -0.000394 -0.000193 0.002500 -2.686573e-25 \n", + "60212 8.504253e-09 -0.000394 -0.000193 0.002500 -2.673378e-25 \n", + "60213 8.504253e-09 -0.000394 -0.000193 0.002500 -2.673378e-25 \n", + "\n", + " momentum_y momentum_z magnetic_field_x magnetic_field_y \\\n", + "entry \n", + "0 2.294092e-25 1.363769e-28 0.000096 0.000047 \n", + "1 -6.696744e-26 2.712237e-28 0.000096 0.000047 \n", + "2 -3.531530e-25 4.040963e-28 0.000096 0.000047 \n", + "3 -5.855783e-25 5.348512e-28 0.000096 0.000047 \n", + "4 -7.288588e-25 6.636673e-28 0.000096 0.000047 \n", + "... ... ... ... ... \n", + "60209 2.252927e-25 4.664605e-25 -0.000096 -0.000047 \n", + "60210 1.489691e-25 4.663268e-25 -0.000096 -0.000047 \n", + "60211 4.996172e-26 4.661934e-25 -0.000096 -0.000047 \n", + "60212 -5.665659e-26 4.660607e-25 -0.000096 -0.000047 \n", + "60213 -5.665659e-26 4.660607e-25 -0.000096 -0.000047 \n", + "\n", + " magnetic_field_z electric_field_x electric_field_y electric_field_z \\\n", + "entry \n", + "0 5.883916 174.266780 85.749975 -2170.178971 \n", + "1 5.883916 174.401945 85.733130 -2170.172812 \n", + "2 5.883916 174.531749 85.770216 -2170.165590 \n", + "3 5.883916 174.636429 85.855583 -2170.158388 \n", + "4 5.883916 174.700050 85.976234 -2170.152276 \n", + "... ... ... ... ... \n", + "60209 5.883917 173.756932 85.321218 2169.629784 \n", + "60210 5.883916 173.796118 85.288087 2169.797504 \n", + "60211 5.883916 173.845427 85.271033 2169.964312 \n", + "60212 5.883916 173.897955 85.272949 2170.130469 \n", + "60213 5.883916 173.897955 85.272949 2170.130469 \n", + "\n", + " electric_potential kinetic_energy track_id \n", + "entry \n", + "0 2.353168 2.000035 0.0 \n", + "1 2.353220 2.000087 0.0 \n", + "2 2.353281 2.000148 0.0 \n", + "3 2.353341 2.000209 0.0 \n", + "4 2.353392 2.000260 0.0 \n", + "... ... ... ... \n", + "60209 2.354339 1.001205 7.0 \n", + "60210 2.353925 1.000791 7.0 \n", + "60211 2.353518 1.000384 7.0 \n", + "60212 2.353116 0.999983 7.0 \n", + "60213 2.353116 0.999983 7.0 \n", + "\n", + "[60214 rows x 20 columns]" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df2" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
polar_angle_to_zpolar_angle_to_bguiding_center_position_xguiding_center_position_yguiding_center_position_zorbital_magnetic_momenttrack_idstep_id
entry
047.00896547.008648-0.000395-0.000195-0.00155.445992e-201.06254.0
147.00806447.007801-0.000395-0.000195-0.00155.445972e-201.06255.0
247.00717047.006964-0.000395-0.000195-0.00155.445957e-201.06256.0
347.00628547.006137-0.000395-0.000195-0.00155.445945e-201.06257.0
447.00540847.005320-0.000395-0.000195-0.00155.445937e-201.06258.0
...........................
5039417.79846317.798961-0.000394-0.0001940.00156.967376e-216.056648.0
5039517.79867217.799203-0.000394-0.0001940.00156.967254e-216.056649.0
5039617.79887617.799436-0.000394-0.0001940.00156.967124e-216.056650.0
5039717.79907917.799662-0.000394-0.0001940.00156.966988e-216.056651.0
5039817.79928017.799882-0.000394-0.0001940.00156.966847e-216.056652.0
\n", + "

50399 rows × 8 columns

\n", + "
" + ], + "text/plain": [ + " polar_angle_to_z polar_angle_to_b guiding_center_position_x \\\n", + "entry \n", + "0 47.008965 47.008648 -0.000395 \n", + "1 47.008064 47.007801 -0.000395 \n", + "2 47.007170 47.006964 -0.000395 \n", + "3 47.006285 47.006137 -0.000395 \n", + "4 47.005408 47.005320 -0.000395 \n", + "... ... ... ... \n", + "50394 17.798463 17.798961 -0.000394 \n", + "50395 17.798672 17.799203 -0.000394 \n", + "50396 17.798876 17.799436 -0.000394 \n", + "50397 17.799079 17.799662 -0.000394 \n", + "50398 17.799280 17.799882 -0.000394 \n", + "\n", + " guiding_center_position_y guiding_center_position_z \\\n", + "entry \n", + "0 -0.000195 -0.0015 \n", + "1 -0.000195 -0.0015 \n", + "2 -0.000195 -0.0015 \n", + "3 -0.000195 -0.0015 \n", + "4 -0.000195 -0.0015 \n", + "... ... ... \n", + "50394 -0.000194 0.0015 \n", + "50395 -0.000194 0.0015 \n", + "50396 -0.000194 0.0015 \n", + "50397 -0.000194 0.0015 \n", + "50398 -0.000194 0.0015 \n", + "\n", + " orbital_magnetic_moment track_id step_id \n", + "entry \n", + "0 5.445992e-20 1.0 6254.0 \n", + "1 5.445972e-20 1.0 6255.0 \n", + "2 5.445957e-20 1.0 6256.0 \n", + "3 5.445945e-20 1.0 6257.0 \n", + "4 5.445937e-20 1.0 6258.0 \n", + "... ... ... ... \n", + "50394 6.967376e-21 6.0 56648.0 \n", + "50395 6.967254e-21 6.0 56649.0 \n", + "50396 6.967124e-21 6.0 56650.0 \n", + "50397 6.966988e-21 6.0 56651.0 \n", + "50398 6.966847e-21 6.0 56652.0 \n", + "\n", + "[50399 rows x 8 columns]" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df3" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
step_idcontinuous_timecontinuous_lengthnumber_of_turnstimeposition_xposition_yposition_zmomentum_xmomentum_y...electric_field_zelectric_potentialkinetic_energytrack_idpolar_angle_to_zpolar_angle_to_bguiding_center_position_xguiding_center_position_yguiding_center_position_zorbital_magnetic_moment
00.03.794667e-133.182840e-0703.794667e-13-0.000395-0.000194-0.002500-7.288185e-252.294092e-25...-2170.1789712.3531682.0000350.0NaNNaNNaNNaNNaNNaN
11.03.794667e-133.182876e-0707.589334e-13-0.000395-0.000194-0.002500-7.611409e-25-6.696744e-26...-2170.1728122.3532202.0000870.0NaNNaNNaNNaNNaNNaN
22.03.794667e-133.182921e-0701.138400e-12-0.000396-0.000194-0.002500-6.775845e-25-3.531530e-25...-2170.1655902.3532812.0001480.0NaNNaNNaNNaNNaNNaN
33.03.794667e-133.182970e-0701.517867e-12-0.000396-0.000195-0.002500-4.908700e-25-5.855783e-25...-2170.1583882.3533412.0002090.0NaNNaNNaNNaNNaNNaN
44.03.794667e-133.183015e-0701.897334e-12-0.000396-0.000195-0.002500-2.294229e-25-7.288588e-25...-2170.1522762.3533922.0002600.0NaNNaNNaNNaNNaNNaN
..................................................................
6020960209.03.794659e-132.252191e-0708.503115e-09-0.000394-0.0001930.002499-1.546179e-252.252927e-25...2169.6297842.3543391.0012057.0NaNNaNNaNNaNNaNNaN
6021060210.03.794659e-132.251720e-0708.503494e-09-0.000394-0.0001930.002500-2.290754e-251.489691e-25...2169.7975042.3539251.0007917.0NaNNaNNaNNaNNaNNaN
6021160211.03.794660e-132.251258e-0708.503874e-09-0.000394-0.0001930.002500-2.686573e-254.996172e-26...2169.9643122.3535181.0003847.0NaNNaNNaNNaNNaNNaN
6021260212.03.794660e-132.250804e-0708.504253e-09-0.000394-0.0001930.002500-2.673378e-25-5.665659e-26...2170.1304692.3531160.9999837.0NaNNaNNaNNaNNaNNaN
6021360213.00.000000e+000.000000e+0008.504253e-09-0.000394-0.0001930.002500-2.673378e-25-5.665659e-26...2170.1304692.3531160.9999837.0NaNNaNNaNNaNNaNNaN
\n", + "

60214 rows × 26 columns

\n", + "
" + ], + "text/plain": [ + " step_id continuous_time continuous_length number_of_turns \\\n", + "0 0.0 3.794667e-13 3.182840e-07 0 \n", + "1 1.0 3.794667e-13 3.182876e-07 0 \n", + "2 2.0 3.794667e-13 3.182921e-07 0 \n", + "3 3.0 3.794667e-13 3.182970e-07 0 \n", + "4 4.0 3.794667e-13 3.183015e-07 0 \n", + "... ... ... ... ... \n", + "60209 60209.0 3.794659e-13 2.252191e-07 0 \n", + "60210 60210.0 3.794659e-13 2.251720e-07 0 \n", + "60211 60211.0 3.794660e-13 2.251258e-07 0 \n", + "60212 60212.0 3.794660e-13 2.250804e-07 0 \n", + "60213 60213.0 0.000000e+00 0.000000e+00 0 \n", + "\n", + " time position_x position_y position_z momentum_x \\\n", + "0 3.794667e-13 -0.000395 -0.000194 -0.002500 -7.288185e-25 \n", + "1 7.589334e-13 -0.000395 -0.000194 -0.002500 -7.611409e-25 \n", + "2 1.138400e-12 -0.000396 -0.000194 -0.002500 -6.775845e-25 \n", + "3 1.517867e-12 -0.000396 -0.000195 -0.002500 -4.908700e-25 \n", + "4 1.897334e-12 -0.000396 -0.000195 -0.002500 -2.294229e-25 \n", + "... ... ... ... ... ... \n", + "60209 8.503115e-09 -0.000394 -0.000193 0.002499 -1.546179e-25 \n", + "60210 8.503494e-09 -0.000394 -0.000193 0.002500 -2.290754e-25 \n", + "60211 8.503874e-09 -0.000394 -0.000193 0.002500 -2.686573e-25 \n", + "60212 8.504253e-09 -0.000394 -0.000193 0.002500 -2.673378e-25 \n", + "60213 8.504253e-09 -0.000394 -0.000193 0.002500 -2.673378e-25 \n", + "\n", + " momentum_y ... electric_field_z electric_potential \\\n", + "0 2.294092e-25 ... -2170.178971 2.353168 \n", + "1 -6.696744e-26 ... -2170.172812 2.353220 \n", + "2 -3.531530e-25 ... -2170.165590 2.353281 \n", + "3 -5.855783e-25 ... -2170.158388 2.353341 \n", + "4 -7.288588e-25 ... -2170.152276 2.353392 \n", + "... ... ... ... ... \n", + "60209 2.252927e-25 ... 2169.629784 2.354339 \n", + "60210 1.489691e-25 ... 2169.797504 2.353925 \n", + "60211 4.996172e-26 ... 2169.964312 2.353518 \n", + "60212 -5.665659e-26 ... 2170.130469 2.353116 \n", + "60213 -5.665659e-26 ... 2170.130469 2.353116 \n", + "\n", + " kinetic_energy track_id polar_angle_to_z polar_angle_to_b \\\n", + "0 2.000035 0.0 NaN NaN \n", + "1 2.000087 0.0 NaN NaN \n", + "2 2.000148 0.0 NaN NaN \n", + "3 2.000209 0.0 NaN NaN \n", + "4 2.000260 0.0 NaN NaN \n", + "... ... ... ... ... \n", + "60209 1.001205 7.0 NaN NaN \n", + "60210 1.000791 7.0 NaN NaN \n", + "60211 1.000384 7.0 NaN NaN \n", + "60212 0.999983 7.0 NaN NaN \n", + "60213 0.999983 7.0 NaN NaN \n", + "\n", + " guiding_center_position_x guiding_center_position_y \\\n", + "0 NaN NaN \n", + "1 NaN NaN \n", + "2 NaN NaN \n", + "3 NaN NaN \n", + "4 NaN NaN \n", + "... ... ... \n", + "60209 NaN NaN \n", + "60210 NaN NaN \n", + "60211 NaN NaN \n", + "60212 NaN NaN \n", + "60213 NaN NaN \n", + "\n", + " guiding_center_position_z orbital_magnetic_moment \n", + "0 NaN NaN \n", + "1 NaN NaN \n", + "2 NaN NaN \n", + "3 NaN NaN \n", + "4 NaN NaN \n", + "... ... ... \n", + "60209 NaN NaN \n", + "60210 NaN NaN \n", + "60211 NaN NaN \n", + "60212 NaN NaN \n", + "60213 NaN NaN \n", + "\n", + "[60214 rows x 26 columns]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df4" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
step_idcontinuous_timecontinuous_lengthnumber_of_turns_xtimeposition_xposition_yposition_zmomentum_xmomentum_y...final_electric_field_yfinal_electric_field_zfinal_electric_potentialfinal_kinetic_energyfinal_polar_angle_to_zfinal_azimuthal_angle_to_xfinal_polar_angle_to_bfinal_orbital_magnetic_momentz_length_internalz_length_integral
00.03.794667e-133.182840e-0703.794667e-13-0.000395-0.000194-0.002500-7.288185e-252.294092e-25...84.703349-1305.9638334.0914213.73828747.00987280.04453147.0095045.446014e-200.0022810.002281
11.03.794667e-133.182876e-0707.589334e-13-0.000395-0.000194-0.002500-7.611409e-25-6.696744e-26...84.703349-1305.9638334.0914213.73828747.00987280.04453147.0095045.446014e-200.0022810.002281
22.03.794667e-133.182921e-0701.138400e-12-0.000396-0.000194-0.002500-6.775845e-25-3.531530e-25...84.703349-1305.9638334.0914213.73828747.00987280.04453147.0095045.446014e-200.0022810.002281
33.03.794667e-133.182970e-0701.517867e-12-0.000396-0.000195-0.002500-4.908700e-25-5.855783e-25...84.703349-1305.9638334.0914213.73828747.00987280.04453147.0095045.446014e-200.0022810.002281
44.03.794667e-133.183015e-0701.897334e-12-0.000396-0.000195-0.002500-2.294229e-25-7.288588e-25...84.703349-1305.9638334.0914213.73828747.00987280.04453147.0095045.446014e-200.0022810.002281
..................................................................
6020960209.03.794659e-132.252191e-0708.503115e-09-0.000394-0.0001930.002499-1.546179e-252.252927e-25...85.2729492170.1304692.3531160.99998330.385302191.96558230.3842946.966103e-210.0010810.001081
6021060210.03.794659e-132.251720e-0708.503494e-09-0.000394-0.0001930.002500-2.290754e-251.489691e-25...85.2729492170.1304692.3531160.99998330.385302191.96558230.3842946.966103e-210.0010810.001081
6021160211.03.794660e-132.251258e-0708.503874e-09-0.000394-0.0001930.002500-2.686573e-254.996172e-26...85.2729492170.1304692.3531160.99998330.385302191.96558230.3842946.966103e-210.0010810.001081
6021260212.03.794660e-132.250804e-0708.504253e-09-0.000394-0.0001930.002500-2.673378e-25-5.665659e-26...85.2729492170.1304692.3531160.99998330.385302191.96558230.3842946.966103e-210.0010810.001081
6021360213.00.000000e+000.000000e+0008.504253e-09-0.000394-0.0001930.002500-2.673378e-25-5.665659e-26...85.2729492170.1304692.3531160.99998330.385302191.96558230.3842946.966103e-210.0010810.001081
\n", + "

60214 rows × 70 columns

\n", + "
" + ], + "text/plain": [ + " step_id continuous_time continuous_length number_of_turns_x \\\n", + "0 0.0 3.794667e-13 3.182840e-07 0 \n", + "1 1.0 3.794667e-13 3.182876e-07 0 \n", + "2 2.0 3.794667e-13 3.182921e-07 0 \n", + "3 3.0 3.794667e-13 3.182970e-07 0 \n", + "4 4.0 3.794667e-13 3.183015e-07 0 \n", + "... ... ... ... ... \n", + "60209 60209.0 3.794659e-13 2.252191e-07 0 \n", + "60210 60210.0 3.794659e-13 2.251720e-07 0 \n", + "60211 60211.0 3.794660e-13 2.251258e-07 0 \n", + "60212 60212.0 3.794660e-13 2.250804e-07 0 \n", + "60213 60213.0 0.000000e+00 0.000000e+00 0 \n", + "\n", + " time position_x position_y position_z momentum_x \\\n", + "0 3.794667e-13 -0.000395 -0.000194 -0.002500 -7.288185e-25 \n", + "1 7.589334e-13 -0.000395 -0.000194 -0.002500 -7.611409e-25 \n", + "2 1.138400e-12 -0.000396 -0.000194 -0.002500 -6.775845e-25 \n", + "3 1.517867e-12 -0.000396 -0.000195 -0.002500 -4.908700e-25 \n", + "4 1.897334e-12 -0.000396 -0.000195 -0.002500 -2.294229e-25 \n", + "... ... ... ... ... ... \n", + "60209 8.503115e-09 -0.000394 -0.000193 0.002499 -1.546179e-25 \n", + "60210 8.503494e-09 -0.000394 -0.000193 0.002500 -2.290754e-25 \n", + "60211 8.503874e-09 -0.000394 -0.000193 0.002500 -2.686573e-25 \n", + "60212 8.504253e-09 -0.000394 -0.000193 0.002500 -2.673378e-25 \n", + "60213 8.504253e-09 -0.000394 -0.000193 0.002500 -2.673378e-25 \n", + "\n", + " momentum_y ... final_electric_field_y final_electric_field_z \\\n", + "0 2.294092e-25 ... 84.703349 -1305.963833 \n", + "1 -6.696744e-26 ... 84.703349 -1305.963833 \n", + "2 -3.531530e-25 ... 84.703349 -1305.963833 \n", + "3 -5.855783e-25 ... 84.703349 -1305.963833 \n", + "4 -7.288588e-25 ... 84.703349 -1305.963833 \n", + "... ... ... ... ... \n", + "60209 2.252927e-25 ... 85.272949 2170.130469 \n", + "60210 1.489691e-25 ... 85.272949 2170.130469 \n", + "60211 4.996172e-26 ... 85.272949 2170.130469 \n", + "60212 -5.665659e-26 ... 85.272949 2170.130469 \n", + "60213 -5.665659e-26 ... 85.272949 2170.130469 \n", + "\n", + " final_electric_potential final_kinetic_energy final_polar_angle_to_z \\\n", + "0 4.091421 3.738287 47.009872 \n", + "1 4.091421 3.738287 47.009872 \n", + "2 4.091421 3.738287 47.009872 \n", + "3 4.091421 3.738287 47.009872 \n", + "4 4.091421 3.738287 47.009872 \n", + "... ... ... ... \n", + "60209 2.353116 0.999983 30.385302 \n", + "60210 2.353116 0.999983 30.385302 \n", + "60211 2.353116 0.999983 30.385302 \n", + "60212 2.353116 0.999983 30.385302 \n", + "60213 2.353116 0.999983 30.385302 \n", + "\n", + " final_azimuthal_angle_to_x final_polar_angle_to_b \\\n", + "0 80.044531 47.009504 \n", + "1 80.044531 47.009504 \n", + "2 80.044531 47.009504 \n", + "3 80.044531 47.009504 \n", + "4 80.044531 47.009504 \n", + "... ... ... \n", + "60209 191.965582 30.384294 \n", + "60210 191.965582 30.384294 \n", + "60211 191.965582 30.384294 \n", + "60212 191.965582 30.384294 \n", + "60213 191.965582 30.384294 \n", + "\n", + " final_orbital_magnetic_moment z_length_internal z_length_integral \n", + "0 5.446014e-20 0.002281 0.002281 \n", + "1 5.446014e-20 0.002281 0.002281 \n", + "2 5.446014e-20 0.002281 0.002281 \n", + "3 5.446014e-20 0.002281 0.002281 \n", + "4 5.446014e-20 0.002281 0.002281 \n", + "... ... ... ... \n", + "60209 6.966103e-21 0.001081 0.001081 \n", + "60210 6.966103e-21 0.001081 0.001081 \n", + "60211 6.966103e-21 0.001081 0.001081 \n", + "60212 6.966103e-21 0.001081 0.001081 \n", + "60213 6.966103e-21 0.001081 0.001081 \n", + "\n", + "[60214 rows x 70 columns]" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
step_idcontinuous_timecontinuous_lengthnumber_of_turns_xtimeposition_xposition_yposition_zmomentum_xmomentum_y...final_electric_field_yfinal_electric_field_zfinal_electric_potentialfinal_kinetic_energyfinal_polar_angle_to_zfinal_azimuthal_angle_to_xfinal_polar_angle_to_bfinal_orbital_magnetic_momentz_length_internalz_length_integral
00.03.794667e-133.182840e-0703.794667e-13-0.000395-0.000194-0.002500-7.288185e-252.294092e-25...84.703349-1305.9638334.0914213.73828747.00987280.04453147.0095045.446014e-200.0022810.002281
11.03.794667e-133.182876e-0707.589334e-13-0.000395-0.000194-0.002500-7.611409e-25-6.696744e-26...84.703349-1305.9638334.0914213.73828747.00987280.04453147.0095045.446014e-200.0022810.002281
22.03.794667e-133.182921e-0701.138400e-12-0.000396-0.000194-0.002500-6.775845e-25-3.531530e-25...84.703349-1305.9638334.0914213.73828747.00987280.04453147.0095045.446014e-200.0022810.002281
33.03.794667e-133.182970e-0701.517867e-12-0.000396-0.000195-0.002500-4.908700e-25-5.855783e-25...84.703349-1305.9638334.0914213.73828747.00987280.04453147.0095045.446014e-200.0022810.002281
44.03.794667e-133.183015e-0701.897334e-12-0.000396-0.000195-0.002500-2.294229e-25-7.288588e-25...84.703349-1305.9638334.0914213.73828747.00987280.04453147.0095045.446014e-200.0022810.002281
..................................................................
62496249.03.794430e-134.350428e-0702.371611e-09-0.000395-0.000196-0.0015017.612101e-256.679571e-26...84.703349-1305.9638334.0914213.73828747.00987280.04453147.0095045.446014e-200.0022810.002281
62506250.03.794430e-134.350621e-0702.371991e-09-0.000395-0.000196-0.0015016.776975e-253.530042e-25...84.703349-1305.9638334.0914213.73828747.00987280.04453147.0095045.446014e-200.0022810.002281
62516251.03.794430e-134.350811e-0702.372370e-09-0.000395-0.000196-0.0015004.910147e-255.854676e-25...84.703349-1305.9638334.0914213.73828747.00987280.04453147.0095045.446014e-200.0022810.002281
62526252.03.794430e-134.351005e-0702.372749e-09-0.000394-0.000195-0.0015002.295824e-257.287953e-25...84.703349-1305.9638334.0914213.73828747.00987280.04453147.0095045.446014e-200.0022810.002281
62536253.01.269808e-131.456110e-0702.372876e-09-0.000394-0.000195-0.0015001.320993e-257.525925e-25...84.703349-1305.9638334.0914213.73828747.00987280.04453147.0095045.446014e-200.0022810.002281
\n", + "

6254 rows × 70 columns

\n", + "
" + ], + "text/plain": [ + " step_id continuous_time continuous_length number_of_turns_x \\\n", + "0 0.0 3.794667e-13 3.182840e-07 0 \n", + "1 1.0 3.794667e-13 3.182876e-07 0 \n", + "2 2.0 3.794667e-13 3.182921e-07 0 \n", + "3 3.0 3.794667e-13 3.182970e-07 0 \n", + "4 4.0 3.794667e-13 3.183015e-07 0 \n", + "... ... ... ... ... \n", + "6249 6249.0 3.794430e-13 4.350428e-07 0 \n", + "6250 6250.0 3.794430e-13 4.350621e-07 0 \n", + "6251 6251.0 3.794430e-13 4.350811e-07 0 \n", + "6252 6252.0 3.794430e-13 4.351005e-07 0 \n", + "6253 6253.0 1.269808e-13 1.456110e-07 0 \n", + "\n", + " time position_x position_y position_z momentum_x \\\n", + "0 3.794667e-13 -0.000395 -0.000194 -0.002500 -7.288185e-25 \n", + "1 7.589334e-13 -0.000395 -0.000194 -0.002500 -7.611409e-25 \n", + "2 1.138400e-12 -0.000396 -0.000194 -0.002500 -6.775845e-25 \n", + "3 1.517867e-12 -0.000396 -0.000195 -0.002500 -4.908700e-25 \n", + "4 1.897334e-12 -0.000396 -0.000195 -0.002500 -2.294229e-25 \n", + "... ... ... ... ... ... \n", + "6249 2.371611e-09 -0.000395 -0.000196 -0.001501 7.612101e-25 \n", + "6250 2.371991e-09 -0.000395 -0.000196 -0.001501 6.776975e-25 \n", + "6251 2.372370e-09 -0.000395 -0.000196 -0.001500 4.910147e-25 \n", + "6252 2.372749e-09 -0.000394 -0.000195 -0.001500 2.295824e-25 \n", + "6253 2.372876e-09 -0.000394 -0.000195 -0.001500 1.320993e-25 \n", + "\n", + " momentum_y ... final_electric_field_y final_electric_field_z \\\n", + "0 2.294092e-25 ... 84.703349 -1305.963833 \n", + "1 -6.696744e-26 ... 84.703349 -1305.963833 \n", + "2 -3.531530e-25 ... 84.703349 -1305.963833 \n", + "3 -5.855783e-25 ... 84.703349 -1305.963833 \n", + "4 -7.288588e-25 ... 84.703349 -1305.963833 \n", + "... ... ... ... ... \n", + "6249 6.679571e-26 ... 84.703349 -1305.963833 \n", + "6250 3.530042e-25 ... 84.703349 -1305.963833 \n", + "6251 5.854676e-25 ... 84.703349 -1305.963833 \n", + "6252 7.287953e-25 ... 84.703349 -1305.963833 \n", + "6253 7.525925e-25 ... 84.703349 -1305.963833 \n", + "\n", + " final_electric_potential final_kinetic_energy final_polar_angle_to_z \\\n", + "0 4.091421 3.738287 47.009872 \n", + "1 4.091421 3.738287 47.009872 \n", + "2 4.091421 3.738287 47.009872 \n", + "3 4.091421 3.738287 47.009872 \n", + "4 4.091421 3.738287 47.009872 \n", + "... ... ... ... \n", + "6249 4.091421 3.738287 47.009872 \n", + "6250 4.091421 3.738287 47.009872 \n", + "6251 4.091421 3.738287 47.009872 \n", + "6252 4.091421 3.738287 47.009872 \n", + "6253 4.091421 3.738287 47.009872 \n", + "\n", + " final_azimuthal_angle_to_x final_polar_angle_to_b \\\n", + "0 80.044531 47.009504 \n", + "1 80.044531 47.009504 \n", + "2 80.044531 47.009504 \n", + "3 80.044531 47.009504 \n", + "4 80.044531 47.009504 \n", + "... ... ... \n", + "6249 80.044531 47.009504 \n", + "6250 80.044531 47.009504 \n", + "6251 80.044531 47.009504 \n", + "6252 80.044531 47.009504 \n", + "6253 80.044531 47.009504 \n", + "\n", + " final_orbital_magnetic_moment z_length_internal z_length_integral \n", + "0 5.446014e-20 0.002281 0.002281 \n", + "1 5.446014e-20 0.002281 0.002281 \n", + "2 5.446014e-20 0.002281 0.002281 \n", + "3 5.446014e-20 0.002281 0.002281 \n", + "4 5.446014e-20 0.002281 0.002281 \n", + "... ... ... ... \n", + "6249 5.446014e-20 0.002281 0.002281 \n", + "6250 5.446014e-20 0.002281 0.002281 \n", + "6251 5.446014e-20 0.002281 0.002281 \n", + "6252 5.446014e-20 0.002281 0.002281 \n", + "6253 5.446014e-20 0.002281 0.002281 \n", + "\n", + "[6254 rows x 70 columns]" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.query(\"track_id == 0\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Step and geometry visualization" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Make a plot\n", + "fig = plt.figure()\n", + "plt.xlabel('position on z-axis (m)')\n", + "plt.ylabel('position on x-axis (m)')\n", + "\n", + "# Draw step position for each track\n", + "for name,group in df.groupby(\"track_id\"):\n", + " plt.plot(group.position_z, group.position_x, marker='', lw=1, alpha=.8, label=f'Track #{name}')\n", + " \n", + "plt.legend(ncol=2)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(-0.0014, 0.0014)" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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iGyASRcRERGRDTDpIiIiIrIBJl1ERERENsCki4iIiMgGmHQRERER2QCTLiIiIiIbYNJFREREZANMuoiIiIhsgEkXERERkQ0w6SIiIiKyASZdRERERDbApIuIiIjIBph0EREREdkAky4iIiIiG2DSRURERGQDTLqIiIiIbIBJFxEREZENMOkiIiIisgFnS3c4ffo0du7cidOnT6O4uBitWrVCr1690K9fP7i6ujZGjERERER2z+yk68svv8R7772Hffv2wd/fH8HBwXBzc8OVK1dw8uRJuLq6YuLEiZg9ezbatGnTmDETERER2R2zkq7evXvDyckJU6ZMwddff43WrVsbbS8rK0NycjLWrFmDPn364MMPP8Sjjz7aKAETERER2SOzzul68803sX//fkybNq1GwgUAarUagwYNwsqVK5GRkYGwsDBrx2nw4Ycfom3btnB1dUVERAR27txZZ/3ExERERETA1dUV7dq1w8qVK2vUSUhIQHh4ONRqNcLDw7F+/XqL+50yZQoUCoXRq2/fvg0bLBERETkMs5KukSNHmt2gn58f7rrrrnoHVJe1a9ciLi4Or7zyClJSUnDPPfdg+PDhyMrKqrV+ZmYmRowYgXvuuQcpKSn461//ihkzZiAhIcFQJzk5GePGjUNsbCwOHTqE2NhYjB07Fnv37rW432HDhiEnJ8fw+uGHHxplHoiIiMj+KERE6rNjXl4e8vLyoNfrjcp79OhhlcBqExkZid69e2PFihWGsq5du+Khhx7CW2+9VaP+7Nmz8d133yEjI8NQNnXqVBw6dAjJyckAgHHjxqGgoAA//vijoc6wYcPg6+uLr776yux+p0yZgmvXrmHDhg31Hl9BQQE0Gg3y8/Ph7e1d73YcUUhICLKzsxEcHIxz5841dThEFuMaJnvHNWyaue/fFt8y4sCBA+jWrRsCAwPRo0cP3HnnnejVq5fh38ZSXl6OAwcOYOjQoUblQ4cORVJSUq37JCcn16gfHR2N/fv3o6Kios461W1a0u+OHTvg7++PTp064emnn0ZeXl6dYyorK0NBQYHRi4iIiByTxbeMeOKJJ9CpUyesWrUKAQEBUCgUjRFXDZcuXYJOp0NAQIBReUBAAHJzc2vdJzc3t9b6lZWVuHTpEgIDA03WqW7T3H6HDx+ORx99FG3atEFmZibmzZuH+++/HwcOHIBara41vrfeeguvv/66eRNAREREds3ipCszMxPr1q1Dhw4dGiOeW7o5yROROhO/2urfXG5Om7eqM27cOMPX3bp1Q58+fdCmTRts3LgRY8aMqTW2uXPn4oUXXjB8X1BQgNDQUJNjISIiIvtlcdL1wAMP4NChQzZPuvz8/KBUKmsc1crLy6txFKqaVquttb6zszNatmxZZ53qNuvTLwAEBgaiTZs2OHHihMk6arXa5FEwIiIiciwWJ12ffPIJJk+ejCNHjqBbt25QqVRG20ePHm214G7k4uKCiIgIbNmyBQ8//LChfMuWLYiJial1n379+uF///ufUdnmzZvRp08fQ9z9+vXDli1bMHPmTKM6/fv3r3e/AHD58mWcPXsWgYGBlg+WiIiIHI9Y6L///a94e3uLQqGo8XJycrK0OYusWbNGVCqVrFq1StLT0yUuLk48PDzk9OnTIiIyZ84ciY2NNdQ/deqUuLu7y8yZMyU9PV1WrVolKpVKvv32W0Od3bt3i1KplPj4eMnIyJD4+HhxdnaWPXv2mN1vYWGhzJo1S5KSkiQzM1O2b98u/fr1k+DgYCkoKDB7fPn5+QJA8vPzGzpVDic4OFgASHBwcFOHQlQvXMNk77iGTTP3/dvipKtNmzbyl7/8RXJzc+sdXEN88MEH0qZNG3FxcZHevXtLYmKiYdvkyZMlKirKqP6OHTukV69e4uLiImFhYbJixYoabX7zzTfSuXNnUalU0qVLF0lISLCo3+LiYhk6dKi0atVKVCqVtG7dWiZPnixZWVkWjY1Jl2n8z072jmuY7B3XsGnmvn9bfJ8uLy8vpKamon379tY95Ea8T1cdeH8Ysndcw2TvuIZNa7T7dI0ZMwbbt29vUHBEREREtxuLT6Tv1KkT5s6di127dqF79+41TqSfMWOG1YIjIiIichT1unrR09MTiYmJSExMNNqmUCiYdBERERHVol43RyUiIiIiy1h8ThcRERERWc6spCs+Ph7FxcVmNbh3715s3LixQUERERERORqzkq709HS0bt0azz33HH788UdcvHjRsK2yshKHDx/Ghx9+iP79+2P8+PG83QERERHRTcw6p+tf//oXDh8+jA8++AATJ05Efn4+lEol1Gq14QhYr1698Mwzz2Dy5Ml8niARERHRTcw+kb5Hjx745z//iZUrV+Lw4cM4ffo0SkpK4OfnhzvvvBN+fn6NGScRERGRXbP46kWFQoGePXuiZ8+ejREPERERkUPi1YtERERENsCki4iIiMgGmHQRERER2QCTLiIiIiIbaHDSVVBQgA0bNiAjI8Ma8RARERE5JIuTrrFjx2L58uUAgJKSEvTp0wdjx45Fjx49kJCQYPUAiYiIiByBxUnXzz//jHvuuQcAsH79eogIrl27hvfeew8LFy60eoBEREREjsDipCs/Px8tWrQAAGzatAmPPPII3N3dMXLkSJw4ccLqARIRERE5AouTrtDQUCQnJ+P69evYtGkThg4dCgC4evUqXF1drR4gERERkSOw+I70cXFxmDhxIjw9PdGmTRsMGjQIQNXHjt27d7d2fEREREQOweKk689//jPuvvtunD17FkOGDIGTU9XBsnbt2vGcLiIiIiITLE66AKBPnz7o06ePUdnIkSOtEhARERGRIzIr6XrhhRfw5ptvwsPDAy+88EKddZcsWWKVwIiIiIgciVlJV0pKCioqKgxfm6JQKKwTFREREZGDMSvp2r59e61fExEREZF5LL5lxIULF0xuO3z4cIOCISIiInJUFidd3bt3x3fffVej/B//+AciIyOtEhQRERGRo7E46Zo9ezbGjRuHqVOnoqSkBNnZ2bj//vvx97//HWvXrm2MGImIiIjsnsVJ16xZs7Bnzx7s3r0bPXr0QI8ePeDm5obDhw9j9OjRjREjERERkd2zOOkCqm6Eescdd+D06dMoKCjA2LFjERAQYO3YiIiIiByGxUlX9RGu3377DYcPH8aKFSswffp0jB07FlevXm2MGImIiIjsnsVJ1/33349x48YhOTkZXbt2xVNPPYWUlBScO3eOz14kIiIiMsHixwBt3rwZUVFRRmXt27fHrl278Le//c1qgRERERE5EouPdN2ccBkacnLCvHnzGhwQERERkSOq1wOvr1+/jsTERGRlZaG8vNxo24wZM6wSGBEREZEjsTjpSklJwYgRI1BcXIzr16+jRYsWuHTpEtzd3eHv78+ki4iIiKgWFn+8OHPmTDz44IO4cuUK3NzcsGfPHpw5cwYRERH4xz/+0RgxEhEREdk9i5Ou1NRUzJo1C0qlEkqlEmVlZQgNDcU777yDv/71r40RIxEREZHdszjpUqlUUCgUAICAgABkZWUBADQajeFrIiIiIjJm8TldvXr1wv79+9GpUyfcd999eO21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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import pyvista as pv\n", + "\n", + "# Open geometry file\n", + "dataset = pv.read(WORKDIR + '../TheBag/geometry_painter.vtp')\n", + "\n", + "# Produce a slice along the x-z axis\n", + "mesh = dataset.slice(normal=[0,1,0])\n", + "\n", + "# Make a plot\n", + "fig = plt.figure()\n", + "plt.xlabel('position on z-axis (m)')\n", + "plt.ylabel('position on x-axis (m)')\n", + "\n", + "# Draw step position for each track\n", + "for name,group in df.groupby(\"track_id\"):\n", + " plt.plot(group.position_z, group.position_x, marker='', lw=1, label=f'Track #{name}')\n", + " \n", + "plt.legend(ncol=3)\n", + "\n", + "# Draw lines in each slice cell\n", + "for ind in range(mesh.n_cells):\n", + " x, y, z = mesh.cell_points(ind).T\n", + "\n", + " if mesh.cell_type(ind) == 3: # VTK_LINE\n", + " line = mpl.lines.Line2D(z, x, lw=2, c='k')\n", + " plt.gca().add_artist(line)\n", + " \n", + " \n", + "# Adjust axis limit to make the trap volume visible\n", + "plt.xlim(-0.0007, 0.0007)\n", + "plt.ylim(-0.0014, 0.0014)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Kassiopeia/Applications/Examples/CMakeLists.txt b/Kassiopeia/Applications/Examples/CMakeLists.txt index a23553d56..a5ae1e036 100644 --- a/Kassiopeia/Applications/Examples/CMakeLists.txt +++ b/Kassiopeia/Applications/Examples/CMakeLists.txt @@ -1,46 +1,27 @@ -set( APPLICATIONS_EXAMPLES_BASENAMES - QuadrupoleTrapAnalysis - MultiFileAnalysis -) -set( APPLICATIONS_EXAMPLES_LIBRARIES ) +option (Kassiopeia_ENABLE_APP "Build Kassiopeia applications" ON) +if (Kassiopeia_ENABLE_APP) -if( Kassiopeia_USE_ROOT ) -list( APPEND APPLICATIONS_EXAMPLES_BASENAMES - TrackMagneticTransitionCheck - DipoleTrapComparison + set( APPLICATIONS_EXAMPLES_BASENAMES + QuadrupoleTrapAnalysis + MultiFileAnalysis + ) + + if( Kassiopeia_USE_ROOT ) + list( APPEND APPLICATIONS_EXAMPLES_BASENAMES + TrackMagneticTransitionCheck + DipoleTrapComparison ) + endif( Kassiopeia_USE_ROOT ) + + set( APPLICATIONS_EXAMPLES_PATH + ${CMAKE_CURRENT_SOURCE_DIR}/Source + ) -list( APPEND APPLICATIONS_EXAMPLES_LIBRARIES - ${ROOT_LIBRARIES} -) -endif( Kassiopeia_USE_ROOT ) + foreach( BASENAME ${APPLICATIONS_EXAMPLES_BASENAMES} ) + add_executable( ${BASENAME} ${APPLICATIONS_EXAMPLES_PATH}/${BASENAME}.cxx ) + target_link_libraries( ${BASENAME} PUBLIC KassiopeiaBindings ) + endforeach( BASENAME ) -list( APPEND APPLICATIONS_EXAMPLES_LIBRARIES - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - ${KEMField_LIBRARIES} - KassiopeiaUtility - KassiopeiaMath - KassiopeiaObjects - KassiopeiaOperators - KassiopeiaFields - KassiopeiaTrajectories - KassiopeiaInteractions - KassiopeiaNavigators - KassiopeiaTerminators - KassiopeiaReaders - KassiopeiaWriters - KassiopeiaVisualization - KassiopeiaSimulation - KassiopeiaBindings -) -set( APPLICATIONS_EXAMPLES_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source -) -kasper_internal_include_directories() -foreach( BASENAME ${APPLICATIONS_EXAMPLES_BASENAMES} ) - add_executable( ${BASENAME} ${APPLICATIONS_EXAMPLES_PATH}/${BASENAME}.cxx ) - target_link_libraries( ${BASENAME} ${APPLICATIONS_EXAMPLES_LIBRARIES} ${EXTERNAL_LIBRARIES} ) -endforeach( BASENAME ) + kasper_install_executables( ${APPLICATIONS_EXAMPLES_BASENAMES} ) -kasper_install_executables( ${APPLICATIONS_EXAMPLES_BASENAMES} ) +endif(Kassiopeia_ENABLE_APP) diff --git a/Kassiopeia/Applications/Examples/Source/CrossSectionBrCalculator.cxx b/Kassiopeia/Applications/Examples/Source/CrossSectionBrCalculator.cxx index ed7f86a7a..201fd495b 100644 --- a/Kassiopeia/Applications/Examples/Source/CrossSectionBrCalculator.cxx +++ b/Kassiopeia/Applications/Examples/Source/CrossSectionBrCalculator.cxx @@ -13,7 +13,7 @@ #include #include -#ifdef Kommon_USE_ROOT +#ifdef KASPER_USE_ROOT #include "KFormulaProcessor.hh" #endif @@ -86,7 +86,7 @@ int main(int argc, char** argv) tVariableProcessor.InsertAfter(&tTokenizer); tIncludeProcessor.InsertAfter(&tVariableProcessor); -#ifdef Kommon_USE_ROOT +#ifdef KASPER_USE_ROOT KFormulaProcessor tFormulaProcessor; tFormulaProcessor.InsertAfter(&tVariableProcessor); tIncludeProcessor.InsertAfter(&tFormulaProcessor); diff --git a/Kassiopeia/Applications/Examples/Source/CrossSectionBthetaCalculator.cxx b/Kassiopeia/Applications/Examples/Source/CrossSectionBthetaCalculator.cxx index 7aa6cc7a5..eb9bc10ee 100644 --- a/Kassiopeia/Applications/Examples/Source/CrossSectionBthetaCalculator.cxx +++ b/Kassiopeia/Applications/Examples/Source/CrossSectionBthetaCalculator.cxx @@ -13,7 +13,7 @@ #include #include -#ifdef Kommon_USE_ROOT +#ifdef KASPER_USE_ROOT #include "KFormulaProcessor.hh" #endif @@ -86,7 +86,7 @@ int main(int argc, char** argv) tVariableProcessor.InsertAfter(&tTokenizer); tIncludeProcessor.InsertAfter(&tVariableProcessor); -#ifdef Kommon_USE_ROOT +#ifdef KASPER_USE_ROOT KFormulaProcessor tFormulaProcessor; tFormulaProcessor.InsertAfter(&tVariableProcessor); tIncludeProcessor.InsertAfter(&tFormulaProcessor); diff --git a/Kassiopeia/Applications/Examples/Source/CrossSectionMagneticFieldCalculator.cxx b/Kassiopeia/Applications/Examples/Source/CrossSectionMagneticFieldCalculator.cxx index 0d6c69654..635ece484 100644 --- a/Kassiopeia/Applications/Examples/Source/CrossSectionMagneticFieldCalculator.cxx +++ b/Kassiopeia/Applications/Examples/Source/CrossSectionMagneticFieldCalculator.cxx @@ -13,7 +13,7 @@ #include #include -#ifdef Kommon_USE_ROOT +#ifdef KASPER_USE_ROOT #include "KFormulaProcessor.hh" #endif @@ -87,7 +87,7 @@ int main(int argc, char** argv) tVariableProcessor.InsertAfter(&tTokenizer); tIncludeProcessor.InsertAfter(&tVariableProcessor); -#ifdef Kommon_USE_ROOT +#ifdef KASPER_USE_ROOT KFormulaProcessor tFormulaProcessor; tFormulaProcessor.InsertAfter(&tVariableProcessor); tIncludeProcessor.InsertAfter(&tFormulaProcessor); diff --git a/Kassiopeia/Applications/Examples/Source/QuadrupoleTrapAnalysis.cxx b/Kassiopeia/Applications/Examples/Source/QuadrupoleTrapAnalysis.cxx index e85ad9cca..2193bbd78 100644 --- a/Kassiopeia/Applications/Examples/Source/QuadrupoleTrapAnalysis.cxx +++ b/Kassiopeia/Applications/Examples/Source/QuadrupoleTrapAnalysis.cxx @@ -27,6 +27,7 @@ int main() // KSDouble& tLength = tWorld.Get< KSDouble >( "time" ); KSReadObjectROOT& tCell = tStepReader.GetObject("component_step_cell"); + auto& tPosition = tCell.Get("guiding_center_position"); auto& tMoment = tCell.Get("orbital_magnetic_moment"); KSDouble tMinMoment; KSDouble tMaxMoment; @@ -39,9 +40,17 @@ int main() tTrackReader++) { tMinMoment = numeric_limits::max(); tMaxMoment = numeric_limits::min(); + cout << tTrackReader.GetLastStepIndex()-tTrackReader.GetFirstStepIndex() << endl; + size_t tSteps = 0; for (tStepReader = tTrackReader.GetFirstStepIndex(); tStepReader <= tTrackReader.GetLastStepIndex(); tStepReader++) { if (tCell.Valid()) { + if (tSteps == 0) { + cout << "first valid: " << tStepReader.GetStepIndex() << endl; + cout << "first position: " << tPosition.Value() << endl; + cout << "first value: " << tMoment.Value() << endl; + } + tSteps++; if (tMoment.Value() > tMaxMoment.Value()) { tMaxMoment = tMoment; } @@ -52,10 +61,20 @@ int main() } } - tDeviation = - 2.0 * ((tMaxMoment.Value() - tMinMoment.Value()) / (tMaxMoment.Value() + tMinMoment.Value())); + cout << "last valid: " << tStepReader.GetStepIndex() << endl; + cout << "last position: " << tPosition.Value() << endl; + cout << "last value: " << tMoment.Value() << endl; + + cout << tSteps << " steps" << endl; + cout << "from " << tTrackReader.GetFirstStepIndex() << " to " << tTrackReader.GetLastStepIndex() << endl; + + cout << "max: " << tMaxMoment.Value() << ", min: " << tMinMoment.Value() << endl; + + tDeviation = 2.0 * ((tMaxMoment.Value() - tMinMoment.Value()) / (tMaxMoment.Value() + tMinMoment.Value())); - cout << "extrema for track <" << tDeviation << ">" << endl; + cout << "extrema for track #" << tTrackReader.GetTrackIndex() << ": <" << tDeviation << ">" << endl; + cout << endl; + //break; } } } diff --git a/Kassiopeia/Applications/FieldCalculation/CMakeLists.txt b/Kassiopeia/Applications/FieldCalculation/CMakeLists.txt index 9d9ca210f..98dcc43d2 100644 --- a/Kassiopeia/Applications/FieldCalculation/CMakeLists.txt +++ b/Kassiopeia/Applications/FieldCalculation/CMakeLists.txt @@ -1,53 +1,35 @@ -set( APPLICATIONS_FIELDS_BASENAMES - SimpleElectricFieldCalculator - SimpleElectricFieldCalculatorAlongZaxis - SimpleElectricFieldCalculatorOverXYplane - SimpleElectricFieldCalculatorFromFile - SimpleElectricFieldCalculatorSpeedTest +option (Kassiopeia_ENABLE_APP "Build Kassiopeia applications" ON) +if (Kassiopeia_ENABLE_APP) - SimpleMagneticFieldCalculator - SimpleMagneticFieldCalculatorAlongZaxis - SimpleMagneticFieldCalculatorOverXYplane - SimpleMagneticFieldCalculatorFromFile - SimpleMagneticFieldCalculatorSpeedTest + set( APPLICATIONS_FIELDS_BASENAMES + SimpleElectricFieldCalculator + SimpleElectricFieldCalculatorAlongZaxis + SimpleElectricFieldCalculatorAlongFieldline + SimpleElectricFieldCalculatorOverXYplane + SimpleElectricFieldCalculatorFromFile + SimpleElectricFieldCalculatorSpeedTest - SimpleMagneticGradientCalculator -) + SimpleMagneticFieldCalculator + SimpleMagneticFieldCalculatorAlongZaxis + SimpleMagneticFieldCalculatorAlongFieldline + SimpleMagneticFieldCalculatorOverXYplane + SimpleMagneticFieldCalculatorFromFile + SimpleMagneticFieldCalculatorSpeedTest -set( APPLICATIONS_FIELDS_LIBRARIES - ${Kommon_LIBRARIES} - ${Kommon_Vtk_LIBRARIES} - ${KGeoBag_LIBRARIES} - ${KEMField_LIBRARIES} - KassiopeiaUtility - KassiopeiaMath - KassiopeiaObjects - KassiopeiaOperators - KassiopeiaFields - KassiopeiaTrajectories - KassiopeiaInteractions - KassiopeiaNavigators - KassiopeiaTerminators - KassiopeiaReaders - KassiopeiaWriters - KassiopeiaSimulation - KassiopeiaBindings -) + SimpleMagneticGradientCalculator + ) -if( KASPER_USE_BOOST ) - list( APPEND APPLICATIONS_FIELDS_LIBRARIES - ${Boost_LIBRARIES} + set( APPLICATIONS_FIELDS_PATH + ${CMAKE_CURRENT_SOURCE_DIR}/Source ) -endif() -set( APPLICATIONS_FIELDS_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source -) + if( NOT BUILD_KSC ) + foreach( BASENAME ${APPLICATIONS_FIELDS_BASENAMES} ) + add_executable( ${BASENAME} ${APPLICATIONS_FIELDS_PATH}/${BASENAME}.cxx ) + target_link_libraries( ${BASENAME} PUBLIC KassiopeiaBindings ) + endforeach( BASENAME ) -kasper_internal_include_directories() -foreach( BASENAME ${APPLICATIONS_FIELDS_BASENAMES} ) - add_executable( ${BASENAME} ${APPLICATIONS_FIELDS_PATH}/${BASENAME}.cxx ) - target_link_libraries( ${BASENAME} ${APPLICATIONS_FIELDS_LIBRARIES} ${EXTERNAL_LIBRARIES} ) -endforeach( BASENAME ) + kasper_install_executables( ${APPLICATIONS_FIELDS_BASENAMES} ) + endif( NOT BUILD_KSC ) -kasper_install_executables( ${APPLICATIONS_FIELDS_BASENAMES} ) +endif(Kassiopeia_ENABLE_APP) diff --git a/Kassiopeia/Applications/FieldCalculation/Source/SimpleElectricFieldCalculatorAlongFieldline.cxx b/Kassiopeia/Applications/FieldCalculation/Source/SimpleElectricFieldCalculatorAlongFieldline.cxx new file mode 100644 index 000000000..014ba5930 --- /dev/null +++ b/Kassiopeia/Applications/FieldCalculation/Source/SimpleElectricFieldCalculatorAlongFieldline.cxx @@ -0,0 +1,156 @@ +#include "KMessage.h" +#include "KSFieldFinder.h" +#include "KSMainMessage.h" +#include "KSRootElectricField.h" +#include "KSRootMagneticField.h" +#include "KSTrajTrajectoryMagnetic.h" +#include "KSTrajIntegratorRK8.h" +#include "KSTrajInterpolatorFast.h" +#include "KSTrajTermPropagation.h" +#include "KSTrajControlTime.h" +#include "KTextFile.h" +#include "KThreeVector.hh" +#include "KXMLInitializer.hh" +#include "KXMLTokenizer.hh" + + +using namespace Kassiopeia; +using namespace katrin; +using namespace KGeoBag; +using namespace std; + +int main(int argc, char** argv) +{ + if (argc < 10) { + cout + << "usage: ./SimpleElectricFieldCalculatorAlongFieldline [ <...>] " << endl << endl + << "Calculate electric field along a magnetic field line, with given start position (x,y,z) and distance between steps (dist), up to max. number of steps (nsteps). " << endl + << "Results are printed to terminal and saved to output file. Multiple electric field names can be specified, as defined in config file. " << endl + << "It is necessary to specify a magnetic field name in addition to the electric field, in order to calculate the electric field line." << endl; + + // output_file can be "-" (-> write to terminal) + exit(-1); + } + + mainmsg(eNormal) << "starting initialization..." << eom; + + auto& tXML = KXMLInitializer::GetInstance(); + tXML.AddDefaultIncludePath(CONFIG_DEFAULT_DIR); + tXML.Configure(argc, argv, true); + + deque tParameters = tXML.GetArguments().ParameterList(); + tParameters.pop_front(); // strip off config file name + + double tX0 = stod(tParameters[0]); + double tY0 = stod(tParameters[1]); + double tZ0 = stod(tParameters[2]); + double tDistance = stod(tParameters[3]); + uint32_t tNumSteps = stoi(tParameters[4]); + + string tOutFileName(tParameters[5]); + ofstream tOutFileStream; + streambuf* tOutFileBuf; + if (tOutFileName == "-") { + tOutFileBuf = cout.rdbuf(); + } + else { + tOutFileStream.open(tOutFileName); + tOutFileBuf = tOutFileStream.rdbuf(); + } + ostream tOutFile(tOutFileBuf); + + mainmsg(eNormal) << "...initialization finished" << eom; + + // initialize magnetic field + KSRootMagneticField tRootMagneticField; + + { + KSMagneticField* tMagneticFieldObject = getMagneticField(tParameters[6]); + tMagneticFieldObject->Initialize(); + tRootMagneticField.AddMagneticField(tMagneticFieldObject); + } + + // initialize electric field + KSRootElectricField tRootElectricField; + + for (size_t tIndex = 7; tIndex < tParameters.size(); tIndex++) { + KSElectricField* tElectricFieldObject = getElectricField(tParameters[tIndex]); + tElectricFieldObject->Initialize(); + tRootElectricField.AddElectricField(tElectricFieldObject); + } + + // intialize magnetic trajectory + auto tMagneticTrajectory = new KSTrajTrajectoryMagnetic(); + auto tMagneticIntegrator = new KSTrajIntegratorRK8(); + auto tMagneticInterpolator = new KSTrajInterpolatorFast(); + auto tMagneticPropagation = new KSTrajTermPropagation(); + tMagneticPropagation->SetDirection(tDistance < 0 ? KSTrajTermPropagation::eBackward : KSTrajTermPropagation::eForward); + auto tMagneticTimeStep = new KSTrajControlTime(); + tMagneticTimeStep->SetTime(fabs(tDistance)); + tMagneticTrajectory->SetIntegrator(tMagneticIntegrator); + tMagneticTrajectory->SetInterpolator(tMagneticInterpolator); + tMagneticTrajectory->AddTerm(tMagneticPropagation); + tMagneticTrajectory->AddControl(tMagneticTimeStep); + + KThreeVector tMagneticField, tElectricField; + double tPotential; + KThreeVector tPosition(tX0, tY0, tZ0); + + uint32_t tStep = 0; + while (tStep < tNumSteps) { + try { + tRootMagneticField.CalculateField(tPosition, 0.0, tMagneticField); + //tRootElectricField.CalculateFieldAndPotential( tPosition, 0., tElectricField, tPotential ); // FIXME: do not use this (issue #144) + tRootElectricField.CalculateField(tPosition, 0.0, tElectricField); + tRootElectricField.CalculatePotential(tPosition, 0.0, tPotential); + } + catch (...) { + mainmsg(eWarning) << "error - cannot calculate field at position <" << tPosition << ">" << eom; + continue; + } + + mainmsg(eNormal) << "Electric Field at position " << tPosition << " is " << tElectricField << " and potential is " + << tPotential << eom; + + tOutFile << std::fixed << std::setprecision(16) + << tPosition.X() << "\t" << tPosition.Y() << "\t" << tPosition.Z() << "\t" + << tElectricField.X() << "\t" << tElectricField.Y() << "\t" << tElectricField.Z() << endl; + + KSParticle tInitialParticle, tFinalParticle; + KThreeVector tCenter; + double tRadius, tTimeStep; + + tInitialParticle.SetMagneticFieldCalculator(&tRootMagneticField); + tFinalParticle.SetMagneticFieldCalculator(&tRootMagneticField); + + tInitialParticle.SetPosition(tPosition); + tInitialParticle.SetMagneticField(tMagneticField); + + if (tStep == 0 && tMagneticField.Z() < 0 && fabs(tMagneticField.Z()) > fabs(tMagneticField.X())+fabs(tMagneticField.Y())) { + tMagneticPropagation->ReverseDirection(); // make sure distance > 0 tracks in positive z-direction + } + + tMagneticTrajectory->CalculateTrajectory(tInitialParticle, tFinalParticle, tCenter, tRadius, tTimeStep); + //tMagneticTrajectory->ExecuteTrajectory(tTimeStep, tFinalParticle); + + tPosition = tFinalParticle.GetPosition(); + tStep += 1; + + mainmsg(eDebug) << "Trajectory calculated next step: center=" << tCenter << " radius=" << tRadius << " timestep=" << tTimeStep << eom; + } + + { + KSMagneticField* tMagneticFieldObject = getMagneticField(tParameters[6]); + tMagneticFieldObject->Deinitialize(); + } + + for (size_t tIndex = 7; tIndex < tParameters.size(); tIndex++) { + KSElectricField* tElectricFieldObject = getElectricField(tParameters[tIndex]); + tElectricFieldObject->Deinitialize(); + } + + if (tOutFileStream.is_open()) + tOutFileStream.close(); + + return 0; +} diff --git a/Kassiopeia/Applications/FieldCalculation/Source/SimpleMagneticFieldCalculator.cxx b/Kassiopeia/Applications/FieldCalculation/Source/SimpleMagneticFieldCalculator.cxx index cbd68342a..8354ddaac 100644 --- a/Kassiopeia/Applications/FieldCalculation/Source/SimpleMagneticFieldCalculator.cxx +++ b/Kassiopeia/Applications/FieldCalculation/Source/SimpleMagneticFieldCalculator.cxx @@ -64,7 +64,7 @@ int main(int argc, char** argv) return 1; } - mainmsg(eNormal) << "Magnetic Field at position " << tPosition << " is " << tMagneticField << eom; + mainmsg(eNormal) << "Magnetic Field at position " << tPosition << " is " << tMagneticField << ", magnitude " << tMagneticField.Magnitude() << eom; for (size_t tIndex = 3; tIndex < tParameters.size(); tIndex++) { KSMagneticField* tMagneticFieldObject = getMagneticField(tParameters[tIndex]); diff --git a/Kassiopeia/Applications/FieldCalculation/Source/SimpleMagneticFieldCalculatorAlongFieldline.cxx b/Kassiopeia/Applications/FieldCalculation/Source/SimpleMagneticFieldCalculatorAlongFieldline.cxx new file mode 100644 index 000000000..139bda444 --- /dev/null +++ b/Kassiopeia/Applications/FieldCalculation/Source/SimpleMagneticFieldCalculatorAlongFieldline.cxx @@ -0,0 +1,134 @@ +#include "KMessage.h" +#include "KSFieldFinder.h" +#include "KSMainMessage.h" +#include "KSRootMagneticField.h" +#include "KSTrajTrajectoryMagnetic.h" +#include "KSTrajIntegratorRK8.h" +#include "KSTrajInterpolatorFast.h" +#include "KSTrajTermPropagation.h" +#include "KSTrajControlTime.h" +#include "KTextFile.h" +#include "KThreeVector.hh" +#include "KXMLInitializer.hh" +#include "KXMLTokenizer.hh" + + +using namespace Kassiopeia; +using namespace katrin; +using namespace KGeoBag; +using namespace std; + +int main(int argc, char** argv) +{ + if (argc < 9) { + cout + << "usage: ./SimpleMagneticFieldCalculatorAlongFieldline [ <...>] " << endl << endl + << "Calculate magnetic field along a magnetic field line, with given start position (x,y,z) and distance between steps (dist), up to max. number of steps (nsteps). " << endl + << "Results are printed to terminal and saved to output file. Multiple magnetic field names can be specified, as defined in config file. " << endl; + // output_file can be "-" (-> write to terminal) + exit(-1); + } + + mainmsg(eNormal) << "starting initialization..." << eom; + + auto& tXML = KXMLInitializer::GetInstance(); + tXML.AddDefaultIncludePath(CONFIG_DEFAULT_DIR); + tXML.Configure(argc, argv, true); + + deque tParameters = tXML.GetArguments().ParameterList(); + tParameters.pop_front(); // strip off config file name + + double tX0 = stod(tParameters[0]); + double tY0 = stod(tParameters[1]); + double tZ0 = stod(tParameters[2]); + double tDistance = stod(tParameters[3]); + uint32_t tNumSteps = stoi(tParameters[4]); + + string tOutFileName(tParameters[5]); + ofstream tOutFileStream; + streambuf* tOutFileBuf; + if (tOutFileName == "-") { + tOutFileBuf = cout.rdbuf(); + } + else { + tOutFileStream.open(tOutFileName); + tOutFileBuf = tOutFileStream.rdbuf(); + } + ostream tOutFile(tOutFileBuf); + + mainmsg(eNormal) << "...initialization finished" << eom; + + // initialize magnetic field + KSRootMagneticField tRootMagneticField; + + for (size_t tIndex = 6; tIndex < tParameters.size(); tIndex++) { + KSMagneticField* tMagneticFieldObject = getMagneticField(tParameters[tIndex]); + tMagneticFieldObject->Initialize(); + tRootMagneticField.AddMagneticField(tMagneticFieldObject); + } + + // intialize magnetic trajectory + auto tMagneticTrajectory = new KSTrajTrajectoryMagnetic(); + auto tMagneticIntegrator = new KSTrajIntegratorRK8(); + auto tMagneticInterpolator = new KSTrajInterpolatorFast(); + auto tMagneticPropagation = new KSTrajTermPropagation(); + tMagneticPropagation->SetDirection(tDistance < 0 ? KSTrajTermPropagation::eBackward : KSTrajTermPropagation::eForward); + auto tMagneticTimeStep = new KSTrajControlTime(); + tMagneticTimeStep->SetTime(fabs(tDistance)); + tMagneticTrajectory->SetIntegrator(tMagneticIntegrator); + tMagneticTrajectory->SetInterpolator(tMagneticInterpolator); + tMagneticTrajectory->AddTerm(tMagneticPropagation); + tMagneticTrajectory->AddControl(tMagneticTimeStep); + + KThreeVector tMagneticField; + KThreeVector tPosition(tX0, tY0, tZ0); + + uint32_t tStep = 0; + while (tStep < tNumSteps) { + try { + tRootMagneticField.CalculateField(tPosition, 0.0, tMagneticField); + } + catch (...) { + mainmsg(eWarning) << "error - cannot calculate field at position <" << tPosition << ">" << eom; + continue; + } + + mainmsg(eNormal) << "Magnetic Field at position " << tPosition << " is " << tMagneticField << ", magnitude " << tMagneticField.Magnitude() << eom; + + tOutFile << std::fixed << std::setprecision(16) + << tPosition.X() << "\t" << tPosition.Y() << "\t" << tPosition.Z() << "\t" + << tMagneticField.X() << "\t" << tMagneticField.Y() << "\t" << tMagneticField.Z() << endl; + + KSParticle tInitialParticle, tFinalParticle; + KThreeVector tCenter; + double tRadius, tTimeStep; + + tInitialParticle.SetMagneticFieldCalculator(&tRootMagneticField); + tFinalParticle.SetMagneticFieldCalculator(&tRootMagneticField); + + tInitialParticle.SetPosition(tPosition); + tInitialParticle.SetMagneticField(tMagneticField); + + if (tStep == 0 && tMagneticField.Z() < 0 && fabs(tMagneticField.Z()) > fabs(tMagneticField.X())+fabs(tMagneticField.Y())) { + tMagneticPropagation->ReverseDirection(); // make sure distance > 0 tracks in positive z-direction + } + + tMagneticTrajectory->CalculateTrajectory(tInitialParticle, tFinalParticle, tCenter, tRadius, tTimeStep); + //tMagneticTrajectory->ExecuteTrajectory(tTimeStep, tFinalParticle); + + tPosition = tFinalParticle.GetPosition(); + tStep += 1; + + mainmsg(eDebug) << "Trajectory calculated next step: center=" << tCenter << " radius=" << tRadius << " timestep=" << tTimeStep << eom; + } + + for (size_t tIndex = 6; tIndex < tParameters.size(); tIndex++) { + KSMagneticField* tMagneticFieldObject = getMagneticField(tParameters[tIndex]); + tMagneticFieldObject->Deinitialize(); + } + + if (tOutFileStream.is_open()) + tOutFileStream.close(); + + return 0; +} diff --git a/Kassiopeia/Applications/FieldCalculation/Source/SimpleMagneticFieldCalculatorAlongZaxis.cxx b/Kassiopeia/Applications/FieldCalculation/Source/SimpleMagneticFieldCalculatorAlongZaxis.cxx index 5b878cb24..e568d5610 100644 --- a/Kassiopeia/Applications/FieldCalculation/Source/SimpleMagneticFieldCalculatorAlongZaxis.cxx +++ b/Kassiopeia/Applications/FieldCalculation/Source/SimpleMagneticFieldCalculatorAlongZaxis.cxx @@ -72,7 +72,7 @@ int main(int argc, char** argv) continue; } - mainmsg(eNormal) << "Magnetic Field at position " << tPosition << " is " << tMagneticField << eom; + mainmsg(eNormal) << "Magnetic Field at position " << tPosition << " is " << tMagneticField << ", magnitude " << tMagneticField.Magnitude() << eom; outFile << std::fixed << std::setprecision(16) << tPosition.X() << "\t" << tPosition.Y() << "\t" << tPosition.Z() << "\t" << tMagneticField.X() << "\t" << tMagneticField.Y() << "\t" diff --git a/Kassiopeia/Applications/FieldCalculation/Source/SimpleMagneticFieldCalculatorOverXYplane.cxx b/Kassiopeia/Applications/FieldCalculation/Source/SimpleMagneticFieldCalculatorOverXYplane.cxx index 510fcefbd..3eef3dbd6 100644 --- a/Kassiopeia/Applications/FieldCalculation/Source/SimpleMagneticFieldCalculatorOverXYplane.cxx +++ b/Kassiopeia/Applications/FieldCalculation/Source/SimpleMagneticFieldCalculatorOverXYplane.cxx @@ -74,7 +74,7 @@ int main(int argc, char** argv) continue; } - mainmsg(eNormal) << "Magnetic Field at position " << tPosition << " is " << tMagneticField << eom; + mainmsg(eNormal) << "Magnetic Field at position " << tPosition << " is " << tMagneticField << ", magnitude " << tMagneticField.Magnitude() << eom; outFile << std::fixed << std::setprecision(16) << tPosition.X() << "\t" << tPosition.Y() << "\t" << tPosition.Z() << "\t" << tMagneticField.X() << "\t" << tMagneticField.Y() << "\t" diff --git a/Kassiopeia/Applications/Other/CMakeLists.txt b/Kassiopeia/Applications/Other/CMakeLists.txt index c43ec19c1..b164eaa67 100644 --- a/Kassiopeia/Applications/Other/CMakeLists.txt +++ b/Kassiopeia/Applications/Other/CMakeLists.txt @@ -1,58 +1,43 @@ -set( APPLICATIONS_OTHER_BASENAMES -) +option (Kassiopeia_ENABLE_APP "Build Kassiopeia applications" ON) +if (Kassiopeia_ENABLE_APP) -if( Kassiopeia_USE_ROOT ) - list( APPEND APPLICATIONS_OTHER_BASENAMES - ROOTFileMerge - ) - if( KASPER_USE_BOOST ) - find_package( Boost 1.44 REQUIRED COMPONENTS program_options) + set( APPLICATIONS_OTHER_BASENAMES ) + + if( Kassiopeia_USE_ROOT ) list( APPEND APPLICATIONS_OTHER_BASENAMES - TrackCompare + ROOTFileMerge ) + if( KASPER_USE_BOOST ) + find_package( Boost ${BOOST_MINIMUM_VERSION} REQUIRED COMPONENTS program_options) + list( APPEND APPLICATIONS_OTHER_BASENAMES + TrackCompare + ) + endif() endif() -endif() - -set( APPLICATIONS_OTHER_LIBRARIES - ${Kommon_LIBRARIES} - ${Kommon_Vtk_LIBRARIES} - ${KGeoBag_LIBRARIES} - ${KEMField_LIBRARIES} - KassiopeiaUtility - KassiopeiaMath - KassiopeiaObjects - KassiopeiaOperators - KassiopeiaFields - KassiopeiaTrajectories - KassiopeiaInteractions - KassiopeiaNavigators - KassiopeiaTerminators - KassiopeiaReaders - KassiopeiaWriters - KassiopeiaSimulation -) - -if( KASPER_USE_BOOST ) - if( Boost_LIBRARIES ) - list( APPEND APPLICATIONS_OTHER_LIBRARIES - ${Boost_LIBRARIES} - ) - endif() - if( TARGET Boost::program_options ) - list( APPEND APPLICATIONS_OTHER_LIBRARIES - Boost::program_options - ) + + set( APPLICATIONS_OTHER_LIBRARIES + KassiopeiaBindings + ) + + if( KASPER_USE_BOOST ) + if( TARGET Boost::program_options ) + list( APPEND APPLICATIONS_OTHER_LIBRARIES + Boost::program_options + ) + endif() endif() -endif() -set( APPLICATIONS_OTHER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source -) + set( APPLICATIONS_OTHER_PATH + ${CMAKE_CURRENT_SOURCE_DIR}/Source + ) + + if( NOT BUILD_KSC ) + foreach( BASENAME ${APPLICATIONS_OTHER_BASENAMES} ) + add_executable( ${BASENAME} ${APPLICATIONS_OTHER_PATH}/${BASENAME}.cxx ) + target_link_libraries( ${BASENAME} PUBLIC ${APPLICATIONS_OTHER_LIBRARIES} ) + endforeach( BASENAME ) -kasper_internal_include_directories() -foreach( BASENAME ${APPLICATIONS_OTHER_BASENAMES} ) - add_executable( ${BASENAME} ${APPLICATIONS_OTHER_PATH}/${BASENAME}.cxx ) - target_link_libraries( ${BASENAME} ${APPLICATIONS_OTHER_LIBRARIES} ${EXTERNAL_LIBRARIES} ) -endforeach( BASENAME ) + kasper_install_executables( ${APPLICATIONS_OTHER_BASENAMES} ) + endif( NOT BUILD_KSC ) -kasper_install_executables( ${APPLICATIONS_OTHER_BASENAMES} ) +endif(Kassiopeia_ENABLE_APP) diff --git a/Kassiopeia/Applications/Simulation/CMakeLists.txt b/Kassiopeia/Applications/Simulation/CMakeLists.txt index 8243006e3..1eb9cfda3 100644 --- a/Kassiopeia/Applications/Simulation/CMakeLists.txt +++ b/Kassiopeia/Applications/Simulation/CMakeLists.txt @@ -1,36 +1,22 @@ -set( MAIN_BASENAMES - Kassiopeia - ParticleGenerator -) +option (Kassiopeia_ENABLE_APP "Build Kassiopeia applications" ON) +if (Kassiopeia_ENABLE_APP) -set( MAIN_LIBRARIES - ${Kommon_LIBRARIES} - ${Kommon_Vtk_LIBRARIES} - ${KGeoBag_LIBRARIES} - ${KEMField_LIBRARIES} - KassiopeiaUtility - KassiopeiaMath - KassiopeiaObjects - KassiopeiaOperators - KassiopeiaFields - KassiopeiaTrajectories - KassiopeiaInteractions - KassiopeiaTerminators - KassiopeiaWriters - KassiopeiaVisualization - KassiopeiaReaders - KassiopeiaSimulation - KassiopeiaBindings -) + set( APPLICATIONS_MAIN_BASENAMES + Kassiopeia + ParticleGenerator + ) -set( MAIN_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source -) + set( APPLICATIONS_MAIN_PATH + ${CMAKE_CURRENT_SOURCE_DIR}/Source + ) -kasper_internal_include_directories() -foreach( BASENAME ${MAIN_BASENAMES} ) - add_executable( ${BASENAME} ${MAIN_PATH}/${BASENAME}.cxx ) - target_link_libraries( ${BASENAME} ${MAIN_LIBRARIES} ${EXTERNAL_LIBRARIES} ) -endforeach( BASENAME ) + if( NOT BUILD_KSC ) + foreach( BASENAME ${APPLICATIONS_MAIN_BASENAMES} ) + add_executable( ${BASENAME} ${APPLICATIONS_MAIN_PATH}/${BASENAME}.cxx ) + target_link_libraries( ${BASENAME} PUBLIC KassiopeiaBindings ) + endforeach( BASENAME ) -kasper_install_executables( ${MAIN_BASENAMES} ) + kasper_install_executables( ${APPLICATIONS_MAIN_BASENAMES} ) + endif( NOT BUILD_KSC ) + +endif(Kassiopeia_ENABLE_APP) diff --git a/Kassiopeia/Applications/Simulation/Source/Kassiopeia.cxx b/Kassiopeia/Applications/Simulation/Source/Kassiopeia.cxx index b225cf07f..e19110c15 100644 --- a/Kassiopeia/Applications/Simulation/Source/Kassiopeia.cxx +++ b/Kassiopeia/Applications/Simulation/Source/Kassiopeia.cxx @@ -19,8 +19,8 @@ int main(int argc, char** argv) if (argc == 1) { std::cout << "usage: ./Kassiopeia [ <...>]" + << " [ -v | -q ] [ -b | -batch ]" << " [ -r variable1=value1 variable2=value ... ] [ --variable3=value3 ... ]" - << " [ -v | -q ]" << std::endl; exit(-1); } diff --git a/Kassiopeia/Applications/Simulation/Source/ParticleGenerator.cxx b/Kassiopeia/Applications/Simulation/Source/ParticleGenerator.cxx index 8d48b3989..12eb6a14f 100644 --- a/Kassiopeia/Applications/Simulation/Source/ParticleGenerator.cxx +++ b/Kassiopeia/Applications/Simulation/Source/ParticleGenerator.cxx @@ -22,7 +22,7 @@ using namespace std; int main(int argc, char** argv) { - if (argc < 2) { + if (argc < 5) { cout << "usage: ./ParticleGenerator [ <...>] " << endl; @@ -83,7 +83,9 @@ int main(int argc, char** argv) << "kinetic_energy_ev\t" << "magnetic_field\t" << "electric_field\t" - << "electric_potential\t" << endl; + << "electric_potential\t" + << "label\t" + << endl; for (size_t tIndex = 2; tIndex < tParameters.size(); tIndex++) { auto* tGeneratorObject = KToolbox::GetInstance().Get(tParameters[tIndex]); @@ -96,12 +98,11 @@ int main(int argc, char** argv) tGeneratorObject->Initialize(); tRootGenerator.SetGenerator(tGeneratorObject); - auto* tEvent = new KSEvent(); - ; - tRootGenerator.SetEvent(tEvent); - for (unsigned i = 0; i < nEvents; i++) { + auto* tEvent = new KSEvent(); + tRootGenerator.SetEvent(tEvent); + try { tRootGenerator.ExecuteGeneration(); } @@ -110,34 +111,43 @@ int main(int argc, char** argv) mainmsg(eWarning) << "error - cannot execute generator <" << tGeneratorObject->GetName() << ">" << eom; return 1; } - } - auto tParticleQueue = tEvent->GetParticleQueue(); - - mainmsg(eNormal) << "Generator <" << tGeneratorObject->GetName() << "> created <" << tParticleQueue.size() - << "> events" << eom; + auto tParticleQueue = tEvent->GetParticleQueue(); + + mainmsg(eNormal) << "Generator <" << tGeneratorObject->GetName() << "> created <" << tParticleQueue.size() + << "> events for iteration " << i+1 << "/" << nEvents << eom; + + for (auto& tParticle : tParticleQueue) { + tParticle->Print(); + + if (!tParticle->IsValid()) + continue; + + outFile << std::setw(20) << std::scientific << std::setprecision(9) + << tParticle->GetIndexNumber() << "\t" + << tParticle->GetPID() << "\t" + << tParticle->GetMass() << "\t" + << tParticle->GetCharge() << "\t" + << tParticle->GetSpinMagnitude() << "\t" + << tParticle->GetGyromagneticRatio() << "\t" + << tParticle->GetTime() << "\t" + << tParticle->GetX() << "\t" << tParticle->GetY() << "\t" << tParticle->GetZ() << "\t" + << tParticle->GetPX() << "\t" << tParticle->GetPY() << "\t" << tParticle->GetPZ() << "\t" + << tParticle->GetKineticEnergy_eV() << "\t" + << tParticle->GetMagneticField().Magnitude() << "\t" + << tParticle->GetElectricField().Magnitude() << "\t" + << tParticle->GetElectricPotential() << "\t" + << "\"" << tParticle->GetLabel() << "\"\t" + << endl; + } - for (auto& tParticle : tParticleQueue) { - tParticle->Print(); + mainmsg(eNormal) << eom; - if (!tParticle->IsValid()) - continue; + delete tEvent; + tRootGenerator.SetEvent(nullptr); - outFile << std::setw(20) << std::fixed << std::setprecision(9) << tParticle->GetIndexNumber() << "\t" - << tParticle->GetPID() << "\t" << tParticle->GetMass() << "\t" << tParticle->GetCharge() << "\t" - << tParticle->GetSpinMagnitude() << "\t" << tParticle->GetGyromagneticRatio() << "\t" - << tParticle->GetTime() << "\t" << tParticle->GetX() << "\t" << tParticle->GetY() << "\t" - << tParticle->GetZ() << "\t" << tParticle->GetPX() << "\t" << tParticle->GetPY() << "\t" - << tParticle->GetPZ() << "\t" << tParticle->GetKineticEnergy_eV() << "\t" - << tParticle->GetMagneticField().Magnitude() << "\t" << tParticle->GetElectricField().Magnitude() - << "\t" << tParticle->GetElectricPotential() << "\t" << endl; } - mainmsg(eNormal) << eom; - - delete tEvent; - tRootGenerator.SetEvent(nullptr); - tRootGenerator.ClearGenerator(tGeneratorObject); tGeneratorObject->Deinitialize(); } diff --git a/Kassiopeia/Applications/Validation/CMakeLists.txt b/Kassiopeia/Applications/Validation/CMakeLists.txt index 3069e9cc0..e0cc4ea73 100644 --- a/Kassiopeia/Applications/Validation/CMakeLists.txt +++ b/Kassiopeia/Applications/Validation/CMakeLists.txt @@ -1,59 +1,47 @@ -# executables -set( VALIDATION_SOURCE_BASENAMES -# TestField -# TestGenerator -# TestTrajectory -# TestSpaceInteraction -# TestInteractionArgon -) +option (Kassiopeia_ENABLE_APP "Build Kassiopeia applications" ON) +if (Kassiopeia_ENABLE_APP) -if(Kassiopeia_USE_ROOT) - list( APPEND VALIDATION_SOURCE_BASENAMES - TestInteraction - TestHydrogenInteraction - TestIonInteraction - TestArgonInteraction - TestGlukhov - TestZonalHarmonicsConvergence - TestRampedField - TestSynchrotron - ) -endif(Kassiopeia_USE_ROOT) + # executables + set( VALIDATION_SOURCE_BASENAMES + TestField + # TestTrajectory + # TestGenerator + # TestSpaceInteraction + # TestInteractionArgon + ) -if(Kassiopeia_USE_VTK) - if(KEMField_USE_VTK) - list( APPEND VALIDATION_SOURCE_BASENAMES - TestPotentialmap + if(Kassiopeia_USE_ROOT) + list( APPEND VALIDATION_SOURCE_BASENAMES + TestInteraction + TestHydrogenInteraction + TestIonInteraction + TestArgonInteraction + TestGlukhov + TestZonalHarmonicsConvergence + TestRampedField + TestSynchrotron ) - endif(KEMField_USE_VTK) -endif(Kassiopeia_USE_VTK) + endif(Kassiopeia_USE_ROOT) -set( VALIDATION_SOURCE_LIBRARIES - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - ${KEMField_LIBRARIES} - KassiopeiaUtility - KassiopeiaMath - KassiopeiaObjects - KassiopeiaOperators - KassiopeiaFields - KassiopeiaTrajectories - KassiopeiaInteractions - KassiopeiaTerminators - KassiopeiaWriters - KassiopeiaVisualization - KassiopeiaReaders - KassiopeiaSimulation - KassiopeiaBindings -) -set( VALIDATION_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source -) -kasper_internal_include_directories() -foreach( BASENAME ${VALIDATION_SOURCE_BASENAMES} ) - add_executable( ${BASENAME} ${VALIDATION_SOURCE_PATH}/${BASENAME}.cxx ) - set_target_properties( ${BASENAME} PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) - target_link_libraries( ${BASENAME} ${VALIDATION_SOURCE_LIBRARIES} ${EXTERNAL_LIBRARIES} ) -endforeach( BASENAME ) + if(Kassiopeia_USE_VTK) + if(KEMField_USE_VTK) + list( APPEND VALIDATION_SOURCE_BASENAMES + TestPotentialmap + ) + endif(KEMField_USE_VTK) + endif(Kassiopeia_USE_VTK) -kasper_install_executables( ${VALIDATION_SOURCE_BASENAMES} ) + set( VALIDATION_SOURCE_PATH + ${CMAKE_CURRENT_SOURCE_DIR}/Source + ) + + if( NOT BUILD_KSC ) + foreach( BASENAME ${VALIDATION_SOURCE_BASENAMES} ) + add_executable( ${BASENAME} ${VALIDATION_SOURCE_PATH}/${BASENAME}.cxx ) + target_link_libraries( ${BASENAME} PUBLIC KassiopeiaBindings ) + endforeach( BASENAME ) + + kasper_install_executables( ${VALIDATION_SOURCE_BASENAMES} ) + endif( NOT BUILD_KSC ) + +endif(Kassiopeia_ENABLE_APP) diff --git a/Kassiopeia/Applications/Validation/Source/TestField.cxx b/Kassiopeia/Applications/Validation/Source/TestField.cxx index 0137dd27c..856487aea 100644 --- a/Kassiopeia/Applications/Validation/Source/TestField.cxx +++ b/Kassiopeia/Applications/Validation/Source/TestField.cxx @@ -26,10 +26,10 @@ #include -using std::stringstream; - using namespace Kassiopeia; +using namespace KGeoBag; using namespace katrin; +using namespace std; int main(int anArgc, char** anArgv) { diff --git a/Kassiopeia/Applications/Visualization/CMakeLists.txt b/Kassiopeia/Applications/Visualization/CMakeLists.txt new file mode 100644 index 000000000..b4269ef91 --- /dev/null +++ b/Kassiopeia/Applications/Visualization/CMakeLists.txt @@ -0,0 +1,23 @@ +option (Kassiopeia_ENABLE_APP "Build Kassiopeia applications" ON) +if (Kassiopeia_ENABLE_APP) + + set( APPLICATIONS_VISUALIZATION_BASENAMES ) + + if( Kassiopeia_USE_ROOT ) + list( APPEND APPLICATIONS_VISUALIZATION_BASENAMES + ZonalHarmonicViewerROOT + ) + endif( Kassiopeia_USE_ROOT ) + + set( APPLICATIONS_VISUALIZATION_PATH + ${CMAKE_CURRENT_SOURCE_DIR}/Source + ) + + foreach( BASENAME ${APPLICATIONS_VISUALIZATION_BASENAMES} ) + add_executable( ${BASENAME} ${APPLICATIONS_VISUALIZATION_PATH}/${BASENAME}.cxx ) + target_link_libraries( ${BASENAME} PUBLIC KassiopeiaBindings ) + endforeach( BASENAME ) + + kasper_install_executables( ${APPLICATIONS_VISUALIZATION_BASENAMES} ) + +endif(Kassiopeia_ENABLE_APP) diff --git a/Kassiopeia/Applications/Visualization/Source/ZonalHarmonicViewerROOT.cxx b/Kassiopeia/Applications/Visualization/Source/ZonalHarmonicViewerROOT.cxx new file mode 100644 index 000000000..7b6d26f8c --- /dev/null +++ b/Kassiopeia/Applications/Visualization/Source/ZonalHarmonicViewerROOT.cxx @@ -0,0 +1,155 @@ +#include "KGCoreMessage.hh" +#include "KGInterfaceBuilder.hh" +#include "KGElectrostaticBoundaryField.hh" +#include "KGStaticElectromagnetField.hh" +#include "KGROOTGeometryPainter.hh" +#include "KSFieldFinder.h" +#include "KSElectricKEMField.h" +#include "KSMagneticKEMField.h" +#include "KSROOTZonalHarmonicsPainter.h" +#include "KROOTWindow.h" +#include "KXMLInitializer.hh" +#include "KXMLTokenizer.hh" +#include "KToolbox.h" + +using namespace KGeoBag; +using namespace Kassiopeia; +using namespace katrin; +using namespace std; + +using KEMField::KGElectrostaticBoundaryField; +using KEMField::KGStaticElectromagnetField; + +int main(int argc, char** argv) +{ + if (argc < 2) { + cout + << "usage: ./ZonalHarmonicViewerROOT [...] --plane={XZ,YZ,XY} [--point='']" + << endl; + return -1; + } + + coremsg(eNormal) << "starting initialization..." << eom; + + auto& tXML = KXMLInitializer::GetInstance(); + tXML.AddDefaultIncludePath(CONFIG_DEFAULT_DIR); + tXML.Configure(argc, argv, true); + + deque tParameters = tXML.GetArguments().ParameterList(); + tParameters.pop_front(); // strip off config file name + + KThreeVector tPlaneNormal(0,1,0); // default to yz-plane + KThreeVector tPlanePoint(0,0,0); + bool tSwapAxes = false; + + auto tOptions = tXML.GetArguments().OptionTable(); + if (tOptions.find("plane") != tOptions.end()) { + if (tOptions["plane"] == "ZX" || tOptions["plane"] == "zx") { + tPlaneNormal = KThreeVector(1, 0, 0); + } + else if (tOptions["plane"] == "XZ" || tOptions["plane"] == "xz") { + tPlaneNormal = KThreeVector(1, 0, 0); + tSwapAxes = true; + } + else if (tOptions["plane"] == "YZ" || tOptions["plane"] == "yz") { + tPlaneNormal = KThreeVector(0 , 0, 0); + } + else if (tOptions["plane"] == "ZY" || tOptions["plane"] == "zy") { + tPlaneNormal = KThreeVector(0 , 0, 0); + tSwapAxes = true; + } + // xy-plane is unsupported for zonal harmonic painter + else + coremsg(eError) << "plane definition <" << tOptions["plane"] << "> is not supported" << eom; + } + if (tOptions.find("point") != tOptions.end()) { + istringstream Converter(tOptions["point"]); + Converter >> tPlanePoint; + } + + deque tFieldList = tParameters; + + coremsg(eNormal) << "...initialization finished" << eom; + + KROOTWindow tWindow; + tWindow.SetName("KGeoBag ROOT Geometry Viewer"); + + KGROOTGeometryPainter tPainter; + tPainter.SetName("ROOT GeometryPainter"); + tPainter.SetDisplayMode(true); + tPainter.SetWriteMode(true); + + tPainter.SetPlaneNormal(tPlaneNormal); + tPainter.SetPlanePoint(tPlanePoint); + tPainter.SetSwapAxis(tSwapAxes); + + coremsg(eNormal) << "painting with plane normal " << tPlaneNormal << ", plane point " << tPlanePoint << eom; + + KSROOTZonalHarmonicsPainter tPainterZH; + tPainterZH.SetName("ROOT ZonalHarmonicsPainter"); + tPainterZH.SetDisplayMode(true); + tPainterZH.SetWriteMode(true); + + tPainterZH.SetDrawSourcePoints(true); + tPainterZH.SetDrawConvergenceArea(true); + tPainterZH.SetDrawExpansionArea(true); + + for (auto& tField : tFieldList) { + KGElectrostaticBoundaryField* tElectricFieldObject = KToolbox::GetInstance().Get(tField); + if (! tElectricFieldObject) { + // necessary if field is define inside the tag + auto* tKEMFieldObject = KToolbox::GetInstance().Get(tField); + if (tKEMFieldObject) + tElectricFieldObject = dynamic_cast(tKEMFieldObject->GetElectricField()); + } + if (tElectricFieldObject) { + coremsg(eNormal) << "adding electric field: " << tField << eom; + tPainterZH.SetElectricFieldName(tField); + + for (auto& tSurface : tElectricFieldObject->GetSurfaces()) { + tPainter.AddSurface(tSurface); + } + for (auto& tSpace : tElectricFieldObject->GetSpaces()) { + tPainter.AddSpace(tSpace); + } + } + + KGStaticElectromagnetField* tMagneticFieldObject = KToolbox::GetInstance().Get(tField); + if (! tMagneticFieldObject) { + // necessary if field is define inside the tag + auto* tKEMFieldObject = KToolbox::GetInstance().Get(tField); + if (tKEMFieldObject) + tMagneticFieldObject = dynamic_cast(tKEMFieldObject->GetMagneticField()); + } + if (tMagneticFieldObject) { + coremsg(eNormal) << "adding magnetic field: " << tField << eom; + tPainterZH.SetMagneticFieldName(tField); + + for (auto& tSurface : tMagneticFieldObject->GetSurfaces()) { + tPainter.AddSurface(tSurface); + } + for (auto& tSpace : tMagneticFieldObject->GetSpaces()) { + tPainter.AddSpace(tSpace); + } + } + } + + // set ZH painiting limits based on geometry + tPainter.Render(); // update bounds + tPainterZH.SetZmin(tPainter.GetXMin()); + tPainterZH.SetZmax(tPainter.GetXMax()); + tPainterZH.SetRmax(max(fabs(tPainter.GetYMin()), fabs(tPainter.GetYMax()))); + + //tPainterZH.SetZdist(); + //tPainterZH.SetRdist(); + + tWindow.AddPainter(&tPainter); + tWindow.AddPainter(&tPainterZH); + tWindow.Render(); + tWindow.Display(); + tWindow.Write(); + tWindow.RemovePainter(&tPainter); + tWindow.RemovePainter(&tPainterZH); + + return 0; +} diff --git a/Kassiopeia/Bindings/CMakeLists.txt b/Kassiopeia/Bindings/CMakeLists.txt index 435c760e5..edf7b8946 100644 --- a/Kassiopeia/Bindings/CMakeLists.txt +++ b/Kassiopeia/Bindings/CMakeLists.txt @@ -64,7 +64,7 @@ set( BINDINGS_HEADER_FILES Generators/Include/KSGenSpinRelativeCompositeBuilder.h Generators/Include/KSGenTimeCompositeBuilder.h Generators/Include/KSGenGeneratorCompositeBuilder.h - + Generators/Include/KSGenGeneratorTextFileBuilder.h # trajectories Trajectories/Include/KSTrajIntegratorRK54Builder.h @@ -205,13 +205,14 @@ if( Kassiopeia_USE_ROOT ) Visualization/Include/KSROOTMagFieldPainterBuilder.h Visualization/Include/KSROOTZonalHarmonicsPainterBuilder.h ) + if( Kassiopeia_USE_VTK ) list( APPEND BINDINGS_HEADER_FILES Visualization/Include/KSVTKGeneratorPainterBuilder.h Visualization/Include/KSVTKTrackPainterBuilder.h Visualization/Include/KSVTKTrackTerminatorPainterBuilder.h ) - endif( Kassiopeia_USE_VTK ) + endif( Kassiopeia_USE_VTK ) endif( Kassiopeia_USE_ROOT ) if( Kassiopeia_USE_VTK ) @@ -287,6 +288,7 @@ set( BINDINGS_SOURCE_FILES Generators/Source/KSGenSpinRelativeCompositeBuilder.cxx Generators/Source/KSGenTimeCompositeBuilder.cxx Generators/Source/KSGenGeneratorCompositeBuilder.cxx + Generators/Source/KSGenGeneratorTextFileBuilder.cxx # trajectories Trajectories/Source/KSTrajIntegratorRK54Builder.cxx @@ -418,7 +420,7 @@ if( Kassiopeia_USE_ROOT ) Generators/Source/KSGenValueHistogramBuilder.cxx Generators/Source/KSGenGeneratorSimulationBuilder.cxx Writers/Source/KSWriteROOTBuilder.cxx - Writers/Source/KSWriteROOTConditionOutputBuilder.cxx + Writers/Source/KSWriteROOTConditionOutputBuilder.cxx Writers/Source/KSWriteROOTConditionPeriodicBuilder.cxx Writers/Source/KSWriteROOTConditionTerminatorBuilder.cxx Writers/Source/KSWriteROOTConditionStepBuilder.cxx @@ -442,53 +444,38 @@ if( Kassiopeia_USE_VTK ) ) endif( Kassiopeia_USE_VTK ) -# libraries -set( BINDINGS_LIBRARIES - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - ${KEMField_LIBRARIES} - KassiopeiaUtility - KassiopeiaObjects - KassiopeiaOperators - KassiopeiaFields - KassiopeiaGenerators - KassiopeiaGeometry - KassiopeiaTrajectories - KassiopeiaInteractions - KassiopeiaModifiers - KassiopeiaNavigators - KassiopeiaTerminators - KassiopeiaWriters - KassiopeiaVisualization - KassiopeiaSimulation -) - -# internal -kasper_internal_include_directories( - Objects/Include - Operators/Include - Fields/Include - Generators/Include - Geometry/Include - Trajectories/Include - Interactions/Include - Modifiers/Include - Navigators/Include - Terminators/Include - Writers/Include - Visualization/Include - Simulation/Include -) - # target add_library( KassiopeiaBindings SHARED ${BINDINGS_SOURCE_FILES} ${BINDINGS_HEADER_FILES} ) -set_target_properties( KassiopeiaBindings PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) + +add_library( KassiopeiaBindingsHeaders INTERFACE ) + +# get header paths from collected header files +foreach(HEADER ${BINDINGS_HEADER_FILES}) + get_filename_component(DIRNAME ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER} DIRECTORY) + target_include_directories(KassiopeiaBindings PUBLIC $) + target_include_directories(KassiopeiaBindingsHeaders INTERFACE $) +endforeach(HEADER) + +target_include_directories(KassiopeiaBindings PUBLIC $ ) target_link_libraries( KassiopeiaBindings - ${BINDINGS_LIBRARIES} + PUBLIC + Kommon + KEMFieldBindings + KassiopeiaFields + KassiopeiaGenerators + KassiopeiaGeometry + KassiopeiaTrajectories + KassiopeiaInteractions + KassiopeiaModifiers + KassiopeiaNavigators + KassiopeiaTerminators + KassiopeiaWriters + KassiopeiaVisualization + KassiopeiaSimulation ) # install kasper_install_headers( ${BINDINGS_HEADER_FILES} ) -kasper_install_libraries( KassiopeiaBindings ) +kasper_install_libraries( KassiopeiaBindings KassiopeiaBindingsHeaders ) diff --git a/Kassiopeia/Bindings/Generators/Include/KSGenGeneratorTextFileBuilder.h b/Kassiopeia/Bindings/Generators/Include/KSGenGeneratorTextFileBuilder.h new file mode 100644 index 000000000..e7a05dc47 --- /dev/null +++ b/Kassiopeia/Bindings/Generators/Include/KSGenGeneratorTextFileBuilder.h @@ -0,0 +1,32 @@ +#ifndef Kassiopeia_KSGenGeneratorTextFileBuilder_h_ +#define Kassiopeia_KSGenGeneratorTextFileBuilder_h_ + +#include "KComplexElement.hh" +#include "KSGenGeneratorTextFile.h" +#include "KToolbox.h" + +using namespace Kassiopeia; +namespace katrin +{ + +typedef KComplexElement KSGenGeneratorTextFileBuilder; + +template<> inline bool KSGenGeneratorTextFileBuilder::AddAttribute(KContainer* aContainer) +{ + if (aContainer->GetName() == "name") { + aContainer->CopyTo(fObject, &KNamed::SetName); + return true; + } + if (aContainer->GetName() == "base") { + aContainer->CopyTo(fObject, &KSGenGeneratorTextFile::SetBase); + return true; + } + if (aContainer->GetName() == "path") { + aContainer->CopyTo(fObject, &KSGenGeneratorTextFile::SetPath); + return true; + } + return false; +} + +} // namespace katrin +#endif diff --git a/Kassiopeia/Bindings/Generators/Include/KSGenValueAngleCosineBuilder.h b/Kassiopeia/Bindings/Generators/Include/KSGenValueAngleCosineBuilder.h index 68c6dfcdc..34862feba 100644 --- a/Kassiopeia/Bindings/Generators/Include/KSGenValueAngleCosineBuilder.h +++ b/Kassiopeia/Bindings/Generators/Include/KSGenValueAngleCosineBuilder.h @@ -4,6 +4,8 @@ #include "KComplexElement.hh" #include "KSGenValueAngleCosine.h" +#include "KStringUtils.h" + using namespace Kassiopeia; namespace katrin { @@ -16,6 +18,14 @@ template<> inline bool KSGenValueAngleCosineBuilder::AddAttribute(KContainer* aC aContainer->CopyTo(fObject, &KNamed::SetName); return true; } + if (aContainer->GetName() == "mode") { + const std::string& tok = aContainer->AsReference(); + if (KStringUtils::IContains(tok, "mol")) + fObject->SetMode(KSGenValueAngleCosine::EDistributionMode::MolecularFlow); + else + fObject->SetMode(KSGenValueAngleCosine::EDistributionMode::Classic); + return true; + } if (aContainer->GetName() == "angle_min") { aContainer->CopyTo(fObject, &KSGenValueAngleCosine::SetAngleMin); return true; diff --git a/Kassiopeia/Bindings/Generators/Source/KSGenGeneratorTextFileBuilder.cxx b/Kassiopeia/Bindings/Generators/Source/KSGenGeneratorTextFileBuilder.cxx new file mode 100644 index 000000000..f62d25de2 --- /dev/null +++ b/Kassiopeia/Bindings/Generators/Source/KSGenGeneratorTextFileBuilder.cxx @@ -0,0 +1,21 @@ +#include "KSGenGeneratorTextFileBuilder.h" + +#include "KSRootBuilder.h" + +using namespace Kassiopeia; +using namespace std; + +namespace katrin +{ + +template<> KSGenGeneratorTextFileBuilder::~KComplexElement() = default; + +STATICINT sKSGenGeneratorTextFileStructure = + KSGenGeneratorTextFileBuilder::Attribute("name") + + KSGenGeneratorTextFileBuilder::Attribute("base") + + KSGenGeneratorTextFileBuilder::Attribute("path"); + +STATICINT sKSGenGeneratorTextFile = + KSRootBuilder::ComplexElement("ksgen_generator_file"); + +} // namespace katrin diff --git a/Kassiopeia/Bindings/Generators/Source/KSGenValueAngleCosineBuilder.cxx b/Kassiopeia/Bindings/Generators/Source/KSGenValueAngleCosineBuilder.cxx index a92ede01a..689e69f64 100644 --- a/Kassiopeia/Bindings/Generators/Source/KSGenValueAngleCosineBuilder.cxx +++ b/Kassiopeia/Bindings/Generators/Source/KSGenValueAngleCosineBuilder.cxx @@ -11,6 +11,7 @@ namespace katrin template<> KSGenValueAngleCosineBuilder::~KComplexElement() = default; STATICINT sKSGenValueAngleCosineStructure = KSGenValueAngleCosineBuilder::Attribute("name") + + KSGenValueAngleCosineBuilder::Attribute("mode") + KSGenValueAngleCosineBuilder::Attribute("angle_min") + KSGenValueAngleCosineBuilder::Attribute("angle_max"); diff --git a/Kassiopeia/Bindings/Simulation/Include/KSRootBuilder.h b/Kassiopeia/Bindings/Simulation/Include/KSRootBuilder.h index fafbf399f..acb98ae5f 100644 --- a/Kassiopeia/Bindings/Simulation/Include/KSRootBuilder.h +++ b/Kassiopeia/Bindings/Simulation/Include/KSRootBuilder.h @@ -30,7 +30,7 @@ template<> inline bool KSRootBuilder::AddElement(KContainer* aContainer) /// NOTE: deprecated legacy support for old field bindings in the tag if (aContainer->Is()) { - mainmsg(eWarning) << "legacy binding for electric field <" << aContainer->GetName() + mainmsg(eInfo) << "legacy binding for electric field <" << aContainer->GetName() << "> is DEPRECATED - please move objects to tag" << eom; auto* tField = new KSElectricKEMField(); @@ -40,7 +40,7 @@ template<> inline bool KSRootBuilder::AddElement(KContainer* aContainer) return true; } if (aContainer->Is()) { - mainmsg(eWarning) << "legacy binding for magnetic field <" << aContainer->GetName() + mainmsg(eInfo) << "legacy binding for magnetic field <" << aContainer->GetName() << "> is DEPRECATED - please move objects to tag" << eom; auto* tField = new KSMagneticKEMField(); diff --git a/Kassiopeia/CMakeLists.txt b/Kassiopeia/CMakeLists.txt index 6f05cfadc..bee5a5249 100644 --- a/Kassiopeia/CMakeLists.txt +++ b/Kassiopeia/CMakeLists.txt @@ -12,8 +12,8 @@ endif() # Kassiopeia version set( MODULE_VERSION_MAJOR 3 ) -set( MODULE_VERSION_MINOR 7 ) -set( MODULE_VERSION_PATCH 7 ) +set( MODULE_VERSION_MINOR 8 ) +set( MODULE_VERSION_PATCH 0 ) set( MODULE_VERSION "${MODULE_VERSION_MAJOR}.${MODULE_VERSION_MINOR}.${MODULE_VERSION_PATCH}" ) #project( Kassiopeia VERSION ${MODULE_VERSION} ) @@ -21,8 +21,6 @@ project( Kassiopeia ) include( KasperDefaults ) -# require c++11 - # module options # build in boost functionality [utilities] SET( Kassiopeia_USE_BOOST ${KASPER_USE_BOOST} ) @@ -36,82 +34,21 @@ kasper_module_paths( Kassiopeia ) # module debugging kasper_module_debug() -if( Kassiopeia_ENABLE_DEBUG ) - add_cflag( Kassiopeia_ENABLE_DEBUG ) -endif() # external dependencies: boost if( Kassiopeia_USE_BOOST ) - find_package( Boost 1.43.0 COMPONENTS filesystem system REQUIRED ) - if( Boost_INCLUDE_DIR ) - kasper_external_include_directories( ${Boost_INCLUDE_DIR} ) - list(APPEND EXTERNAL_LIBRARIES ${Boost_LIBRARIES} ) - else() - list(APPEND EXTERNAL_LIBRARIES Boost::headers Boost::filesystem Boost::system ) - endif() - add_definitions( -DKassiopeia_USE_BOOST ) -endif() + find_package( Boost ${BOOST_MINIMUM_VERSION} REQUIRED COMPONENTS filesystem system ) +endif( Kassiopeia_USE_BOOST ) # external dependencies: root if( Kassiopeia_USE_ROOT ) - find_package( ROOT 5.24.0 REQUIRED ) - kasper_external_include_directories( ${ROOT_INCLUDE_DIRS} ) - add_definitions( -DKassiopeia_USE_ROOT ) -endif() + find_package( ROOT ${ROOT_MINIMUM_VERSION} CONFIG REQUIRED ) +endif( Kassiopeia_USE_ROOT ) # external dependencies: vtk if( Kassiopeia_USE_VTK ) - kasper_find_vtk() - add_definitions( -DKassiopeia_USE_VTK ) -endif() - - -# internal dependencies: kommon -kasper_find_module( Kommon ) -foreach( FLAG ${Kommon_CFLAGS} ) - add_definitions( -D${FLAG} ) -endforeach() - -# internal dependencies: kgeobag -kasper_find_module( KGeoBag ) -foreach( FLAG ${KGeoBag_CFLAGS} ) - add_definitions( -D${FLAG} ) -endforeach() - -# # internal dependencies: kemfield -kasper_find_module( KEMField ) -foreach( FLAG ${KEMField_CFLAGS} ) - add_definitions( -D${FLAG} ) - if( ${FLAG} STREQUAL KEMFIELD_USE_MPI ) - find_package(MPI) - if (MPI_FOUND) - include_directories(${MPI_INCLUDE_PATH}) - endif() - endif() - endforeach() - -if (KEMField_USE_MPI) - find_package(MPI) - if (MPI_FOUND) - if (MPI_COMPILER) # MPICH2 style - set (CMAKE_C_COMPILER ${MPI_COMPILER}) - set (CMAKE_CXX_COMPILER ${MPI_COMPILER}) - else () # OpenMPI style - set (CMAKE_C_COMPILER ${MPI_C_COMPILER}) - set (CMAKE_CXX_COMPILER ${MPI_CXX_COMPILER}) - endif () - else () - set (CMAKE_C_COMPILER mpicc) - set (CMAKE_CXX_COMPILER mpicxx) - endif () - set (STATIC_LIBRARY_SUFFIX _mpi) - set (SHARED_LIBRARY_SUFFIX _mpi) - set (CMAKE_STATIC_LIBRARY_SUFFIX ${STATIC_LIBRARY_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}) - set (CMAKE_SHARED_LIBRARY_SUFFIX ${SHARED_LIBRARY_SUFFIX}${CMAKE_SHARED_LIBRARY_SUFFIX}) - set (CMAKE_EXECUTABLE_SUFFIX ${SHARED_LIBRARY_SUFFIX}${CMAKE_EXECUTABLE_SUFFIX}) - set (CMAKE_EXECUTABLE_SUFFIX ${CMAKE_EXECUTABLE_SUFFIX} PARENT_SCOPE) -endif () - + find_package(VTK CONFIG REQUIRED) +endif( Kassiopeia_USE_VTK ) # subdirectories add_subdirectory( Documentation ) @@ -130,18 +67,18 @@ add_subdirectory( Modifiers ) add_subdirectory( Writers ) add_subdirectory( Simulation ) add_subdirectory( Readers ) -add_subdirectory( XML ) add_subdirectory( Visualization ) add_subdirectory( Bindings ) add_subdirectory( Python ) add_subdirectory( Applications/Simulation ) add_subdirectory( Applications/FieldCalculation ) - - add_subdirectory( Applications/Validation ) -if( Kassiopeia_USE_ROOT ) - add_subdirectory( Applications/Examples ) - add_subdirectory( Applications/Other ) -endif( ) +add_subdirectory( Applications/Examples ) +add_subdirectory( Applications/Other ) +add_subdirectory( Applications/Visualization ) +add_subdirectory( XML ) kasper_install_module() + +# Install code examples +install(DIRECTORY AnalysisExamples/ DESTINATION ${KASPER_INSTALL_DIR}/examples/Kassiopeia) diff --git a/Kassiopeia/Fields/CMakeLists.txt b/Kassiopeia/Fields/CMakeLists.txt index 7e899211b..10d149c4a 100644 --- a/Kassiopeia/Fields/CMakeLists.txt +++ b/Kassiopeia/Fields/CMakeLists.txt @@ -1,48 +1,47 @@ # header files set( FIELDS_HEADER_BASENAMES - KSElectricKEMField.h - KSFieldsMessage.h - KSExampleFields.h - KSFieldFinder.h + KSElectricKEMField.h + KSFieldsMessage.h + KSExampleFields.h + KSFieldFinder.h KSMagneticKEMField.h ) set( FIELDS_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Include + ${CMAKE_CURRENT_SOURCE_DIR}/Include ) foreach( BASENAME ${FIELDS_HEADER_BASENAMES} ) - list( APPEND FIELDS_HEADER_FILENAMES ${FIELDS_HEADER_PATH}/${BASENAME} ) + list( APPEND FIELDS_HEADER_FILENAMES ${FIELDS_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files set( FIELDS_SOURCE_BASENAMES KSElectricKEMField.cxx - KSFieldsMessage.cxx - KSExampleFields.cxx - KSFieldFinder.cxx - KSMagneticKEMField.cxx + KSFieldsMessage.cxx + KSExampleFields.cxx + KSFieldFinder.cxx + KSMagneticKEMField.cxx ) set( FIELDS_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source + ${CMAKE_CURRENT_SOURCE_DIR}/Source ) foreach( BASENAME ${FIELDS_SOURCE_BASENAMES} ) - list( APPEND FIELDS_SOURCE_FILENAMES ${FIELDS_SOURCE_PATH}/${BASENAME} ) + list( APPEND FIELDS_SOURCE_FILENAMES ${FIELDS_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) # library -kasper_internal_include_directories( ${FIELDS_HEADER_PATH} ) add_library( KassiopeiaFields SHARED ${FIELDS_SOURCE_FILENAMES} ${FIELDS_HEADER_FILENAMES} ) -set_target_properties( KassiopeiaFields PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) + +target_include_directories(KassiopeiaFields + PUBLIC $ $ ) target_link_libraries( KassiopeiaFields - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - ${KEMField_LIBRARIES} - KassiopeiaUtility - KassiopeiaObjects - KassiopeiaOperators + PUBLIC + KassiopeiaOperators + KEMFieldsElectric + KEMFieldsMagnetic ) # install diff --git a/Kassiopeia/Fields/Include/KSElectricKEMField.h b/Kassiopeia/Fields/Include/KSElectricKEMField.h index 1391bd5f0..47aba027e 100644 --- a/Kassiopeia/Fields/Include/KSElectricKEMField.h +++ b/Kassiopeia/Fields/Include/KSElectricKEMField.h @@ -29,7 +29,7 @@ class KSElectricKEMField : public KSElectricField ~KSElectricKEMField() override; void SetElectricField(KEMField::KElectricField* field); - const KEMField::KElectricField* GetElectricField(); + KEMField::KElectricField* GetElectricField(); void CalculatePotential(const KGeoBag::KThreeVector& aSamplePoint, const double& aSampleTime, double& aPotential) override; diff --git a/Kassiopeia/Fields/Include/KSMagneticKEMField.h b/Kassiopeia/Fields/Include/KSMagneticKEMField.h index 63682dc6a..6e81668da 100644 --- a/Kassiopeia/Fields/Include/KSMagneticKEMField.h +++ b/Kassiopeia/Fields/Include/KSMagneticKEMField.h @@ -28,7 +28,7 @@ class KSMagneticKEMField : public KSMagneticField ~KSMagneticKEMField() override; void SetMagneticField(KEMField::KMagneticField* field); - const KEMField::KMagneticField* GetMagneticField(); + KEMField::KMagneticField* GetMagneticField(); void CalculatePotential(const KGeoBag::KThreeVector& aSamplePoint, const double& aSampleTime, KGeoBag::KThreeVector& aPotential) override; diff --git a/Kassiopeia/Fields/Source/KSElectricKEMField.cxx b/Kassiopeia/Fields/Source/KSElectricKEMField.cxx index 552b29792..dcd40048a 100644 --- a/Kassiopeia/Fields/Source/KSElectricKEMField.cxx +++ b/Kassiopeia/Fields/Source/KSElectricKEMField.cxx @@ -35,7 +35,7 @@ void KSElectricKEMField::SetElectricField(KEMField::KElectricField* field) fField = field; } -const KEMField::KElectricField* KSElectricKEMField::GetElectricField() +KEMField::KElectricField* KSElectricKEMField::GetElectricField() { return fField; } diff --git a/Kassiopeia/Fields/Source/KSMagneticKEMField.cxx b/Kassiopeia/Fields/Source/KSMagneticKEMField.cxx index eeb047b2e..b6e3cf3b0 100644 --- a/Kassiopeia/Fields/Source/KSMagneticKEMField.cxx +++ b/Kassiopeia/Fields/Source/KSMagneticKEMField.cxx @@ -36,7 +36,7 @@ void KSMagneticKEMField::SetMagneticField(KEMField::KMagneticField* field) fField = field; } -const KEMField::KMagneticField* KSMagneticKEMField::GetMagneticField() +KEMField::KMagneticField* KSMagneticKEMField::GetMagneticField() { return fField; } diff --git a/Kassiopeia/Generators/CMakeLists.txt b/Kassiopeia/Generators/CMakeLists.txt index 1aad29f54..21d0f3263 100644 --- a/Kassiopeia/Generators/CMakeLists.txt +++ b/Kassiopeia/Generators/CMakeLists.txt @@ -60,6 +60,7 @@ set( GENERATORS_HEADER_BASENAMES KSGenRelaxation.h KSGenGeneratorComposite.h + KSGenGeneratorTextFile.h ) if( Kassiopeia_USE_ROOT ) @@ -140,6 +141,7 @@ set( GENERATORS_SOURCE_BASENAMES KSGenRelaxation.cxx KSGenGeneratorComposite.cxx + KSGenGeneratorTextFile.cxx ) if( Kassiopeia_USE_ROOT ) @@ -176,22 +178,20 @@ foreach( BASENAME ${GENERATORS_DATA_BASENAMES} ) endforeach( BASENAME ) # library -kasper_internal_include_directories( ${GENERATORS_HEADER_PATH} ../Readers/Include ) -add_library( KassiopeiaGenerators SHARED ${GENERATORS_SOURCE_FILENAMES} ${GENERATORS_HEADER_FILENAMES} ) -set_target_properties( KassiopeiaGenerators PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) +add_library( KassiopeiaGenerators SHARED + ${GENERATORS_SOURCE_FILENAMES} ${GENERATORS_HEADER_FILENAMES} ) + +target_include_directories(KassiopeiaGenerators + PUBLIC $ $ ) target_link_libraries( KassiopeiaGenerators - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - KassiopeiaUtility - KassiopeiaObjects - KassiopeiaOperators - KassiopeiaReaders + PUBLIC + KassiopeiaOperators + KassiopeiaReaders + KGeoBagRandom + KGeoBagMesh + ROOT::Tree ) -if( Kassiopeia_USE_ROOT ) - target_link_libraries( KassiopeiaGenerators ${ROOT_LIBRARIES} ) -endif( Kassiopeia_USE_ROOT ) - # install kasper_install_headers( ${GENERATORS_HEADER_FILENAMES} ) kasper_install_data( ${GENERATORS_DATA_FILENAMES} ) diff --git a/Kassiopeia/Generators/Include/KSGenGeneratorTextFile.h b/Kassiopeia/Generators/Include/KSGenGeneratorTextFile.h new file mode 100644 index 000000000..518b03c7d --- /dev/null +++ b/Kassiopeia/Generators/Include/KSGenGeneratorTextFile.h @@ -0,0 +1,47 @@ +#ifndef Kassiopeia_KSGenGeneratorTextFile_h_ +#define Kassiopeia_KSGenGeneratorTextFile_h_ + +#include "KField.h" +#include "KSComponentTemplate.h" +#include "KSGenerator.h" +#include "KSParticle.h" +#include "KTextFile.h" + +#include +#include + +namespace Kassiopeia +{ + +class KSGenGeneratorTextFile : public KSComponentTemplate +{ + public: + KSGenGeneratorTextFile(); + KSGenGeneratorTextFile(const KSGenGeneratorTextFile& aCopy); + KSGenGeneratorTextFile* Clone() const override; + ~KSGenGeneratorTextFile() override; + + public: + void ExecuteGeneration(KSParticleQueue& aPrimaries) override; + + public: + // note that some of these member variables cannot be set via XML bindings yet + ; + K_SET_GET(std::string, Base); + ; + K_SET_GET(std::string, Path); + ; + + protected: + void InitializeComponent() override; + void DeinitializeComponent() override; + + void GenerateParticlesFromFile(KSParticleQueue& aParticleQueue); + + private: + katrin::KTextFile* fTextFile; +}; + +} // namespace Kassiopeia + +#endif diff --git a/Kassiopeia/Generators/Include/KSGenValueAngleCosine.h b/Kassiopeia/Generators/Include/KSGenValueAngleCosine.h index 456e58075..f6162ecbb 100644 --- a/Kassiopeia/Generators/Include/KSGenValueAngleCosine.h +++ b/Kassiopeia/Generators/Include/KSGenValueAngleCosine.h @@ -18,8 +18,14 @@ class KSGenValueAngleCosine : public KSComponentTemplate& aDicedValues) override; public: + enum EDistributionMode { + Classic, + MolecularFlow + }; + K_SET_GET(double, AngleMin) K_SET_GET(double, AngleMax) + K_SET_GET(EDistributionMode, Mode) }; } // namespace Kassiopeia diff --git a/Kassiopeia/Generators/Source/KSGenGeneratorTextFile.cxx b/Kassiopeia/Generators/Source/KSGenGeneratorTextFile.cxx new file mode 100644 index 000000000..c7e407136 --- /dev/null +++ b/Kassiopeia/Generators/Source/KSGenGeneratorTextFile.cxx @@ -0,0 +1,129 @@ +#include "KSGenGeneratorTextFile.h" + +#include "KSGeneratorsMessage.h" +#include "KSParticleFactory.h" +#include "KStringUtils.h" + +using namespace std; +using namespace katrin; +using KGeoBag::KThreeVector; +using katrin::KTextFile; + +namespace Kassiopeia +{ + +KSGenGeneratorTextFile::KSGenGeneratorTextFile() : + fBase(""), + fPath("./") +{} +KSGenGeneratorTextFile::KSGenGeneratorTextFile(const KSGenGeneratorTextFile& aCopy) : + KSComponent(aCopy), + fBase(aCopy.fBase), + fPath(aCopy.fPath) +{} +KSGenGeneratorTextFile* KSGenGeneratorTextFile::Clone() const +{ + return new KSGenGeneratorTextFile(*this); +} +KSGenGeneratorTextFile::~KSGenGeneratorTextFile() = default; + +void KSGenGeneratorTextFile::ExecuteGeneration(KSParticleQueue& aPrimaries) +{ + KSParticleQueue tParticleQueue; + GenerateParticlesFromFile(tParticleQueue); + + aPrimaries.assign(tParticleQueue.begin(), tParticleQueue.end()); + + // check if particle state is valid + KSParticleIt tParticleIt; + for (tParticleIt = aPrimaries.begin(); tParticleIt != aPrimaries.end(); tParticleIt++) { + auto* tParticle = new KSParticle(**tParticleIt); + if (!tParticle->IsValid()) { + tParticle->Print(); + delete tParticle; + genmsg(eError) << "invalid particle state in generator <" << GetName() << ">" << eom; + } + delete tParticle; + } + + return; +} + +void KSGenGeneratorTextFile::InitializeComponent() +{ + fTextFile = katrin::KTextFile::CreateOutputTextFile(fPath, fBase); + fTextFile->AddToPaths(DATA_DEFAULT_DIR); + fTextFile->AddToPaths(SCRATCH_DEFAULT_DIR); + + if (! fTextFile->Open()) { + genmsg(eError) << "file generator <" << GetName() << " cannot open input file <" << fPath << ">" << eom; + } + + return; +} +void KSGenGeneratorTextFile::DeinitializeComponent() +{ + return; +} + +void KSGenGeneratorTextFile::GenerateParticlesFromFile(KSParticleQueue& aParticleQueue) +{ + auto ifs = fTextFile->File(); + if (ifs && ifs->is_open()) { + string buf; + while (getline(*ifs, buf)) { + if (buf.empty() || buf[0] == '#') + continue; + + vector fields; + KStringUtils::Split(buf, " \t", fields); + + if (fields.size() < 10) { + genmsg(eError) << "file generator <" << GetName() << " cannot parse input file with " << fields.size() << " columns (needs at least 10)" << eom; + } + + // Format: + // # index_number pid mass charge total_spin gyromagnetic_ratio time position_x position_y position_z momentum_x momentum_y momentum_z kinetic_energy_ev magnetic_field electric_field electric_potential label + + size_t k = 0; // used to iterate over colums + + uint32_t tIndex = fields[k+0]; + int32_t tPID = fields[k+1]; + k += 2; + + KSParticle* tParticle = KSParticleFactory::GetInstance().Create(tPID); + tParticle->SetIndexNumber(tIndex); + + if (fields.size() >= 14) { + // long fromat - contains mass, charge etc. + // if ((tParticle->GetMass() != fields[2]) || (tParticle->GetCharge() != fields[3]) || + // (tParticle->GetSpinMagnitude() != fields[4]) || (tParticle->GetGyromagneticRatio() == fields[5])) { + // genmsg(eWarning) << "The particle mass/charge/etc. does not match PID <" << tPID << "> for index <" << tIndex << ">" << eom; + // } + + k += 4; // skip four columns + } + + tParticle->SetTime(fields[k+0]); + tParticle->SetPosition(KThreeVector(fields[k+1], fields[k+2], fields[k+3])); + tParticle->SetMomentum(KThreeVector(fields[k+4], fields[k+5], fields[k+6]).Unit()); + tParticle->SetKineticEnergy_eV(fields[k+7]); + k += 7; + + if (fields.size() > k+1) { + genmsg(eInfo) << "Ignored " << fields.size()-k << " extra columns for index <" << tIndex << ">" << eom; + } + + tParticle->AddLabel(GetName()); + tParticle->AddLabel(std::to_string(tIndex)); + + aParticleQueue.push_back(tParticle); + } + } + + genmsg_debug("file generator <" << GetName() << "> creates " << aParticleQueue.size() << " particles" << eom); + + return; +} + +} // namespace Kassiopeia diff --git a/Kassiopeia/Generators/Source/KSGenValueAngleCosine.cxx b/Kassiopeia/Generators/Source/KSGenValueAngleCosine.cxx index 2d0f1c69c..81986f10e 100644 --- a/Kassiopeia/Generators/Source/KSGenValueAngleCosine.cxx +++ b/Kassiopeia/Generators/Source/KSGenValueAngleCosine.cxx @@ -13,7 +13,8 @@ KSGenValueAngleCosine::KSGenValueAngleCosine() : fAngleMin(0.), fAngleMax(0.) {} KSGenValueAngleCosine::KSGenValueAngleCosine(const KSGenValueAngleCosine& aCopy) : KSComponent(aCopy), fAngleMin(aCopy.fAngleMin), - fAngleMax(aCopy.fAngleMax) + fAngleMax(aCopy.fAngleMax), + fMode(EDistributionMode::Classic) {} KSGenValueAngleCosine* KSGenValueAngleCosine::Clone() const { @@ -27,12 +28,23 @@ void KSGenValueAngleCosine::DiceValue(std::vector& aDicedValues) genmsg_assert(fAngleMin, >= 0); genmsg_assert(fAngleMax, <= 90); genmsg_assert(fAngleMin, <= 90); - double tsinThetaSquaredMin = pow(sin((katrin::KConst::Pi() / 180.) * fAngleMin), 2); - double tsinThetaSquaredMax = pow(sin((katrin::KConst::Pi() / 180.) * fAngleMax), 2); - //Random generation follows Eq. 12 from J. Greenwood, Vacuum, 67 (2002), pp. 217-222 - double tsinThetaSquared = KRandom::GetInstance().Uniform(tsinThetaSquaredMin, tsinThetaSquaredMax); - double tAngle = asin(sqrt(tsinThetaSquared)); + double tAngle = 0.; + if (fMode == EDistributionMode::MolecularFlow) { + double tsinThetaSquaredMin = pow(sin((katrin::KConst::Pi() / 180.) * fAngleMin), 2); + double tsinThetaSquaredMax = pow(sin((katrin::KConst::Pi() / 180.) * fAngleMax), 2); + + //Random generation follows Eq. 12 from J. Greenwood, Vacuum, 67 (2002), pp. 217-222 + double tsinThetaSquared = KRandom::GetInstance().Uniform(tsinThetaSquaredMin, tsinThetaSquaredMax); + tAngle = asin(sqrt(tsinThetaSquared)); + } + else if (fMode == EDistributionMode::Classic) { + double tSinThetaMin = sin( (katrin::KConst::Pi() / 180.) * fAngleMin ); + double tSinThetaMax = sin( (katrin::KConst::Pi() / 180.) * fAngleMax ); + + double tSinTheta = KRandom::GetInstance().Uniform( tSinThetaMin, tSinThetaMax ); + tAngle = acos( sqrt( 1. - tSinTheta*tSinTheta ) ); + } aDicedValues.push_back((180.0 / katrin::KConst::Pi()) * tAngle); diff --git a/Kassiopeia/Generators/Source/KSGenValueSet.cxx b/Kassiopeia/Generators/Source/KSGenValueSet.cxx index bfc7def08..26cff8ea4 100644 --- a/Kassiopeia/Generators/Source/KSGenValueSet.cxx +++ b/Kassiopeia/Generators/Source/KSGenValueSet.cxx @@ -23,7 +23,10 @@ void KSGenValueSet::DiceValue(std::vector& aDicedValues) { double tValue; double tValueCount = fValueCount; - double tValueIncrement = (fValueStop - fValueStart) / ((double) (tValueCount > 1 ? tValueCount - 1 : 1)); + double tValueIncrement = fValueIncrement; + + if (tValueCount != 0) + tValueIncrement = (fValueStop - fValueStart) / ((double) (tValueCount > 1 ? tValueCount - 1 : 1)); if (fValueIncrement != 0.) { if ((fValueCount > 0) && (fValueIncrement != tValueIncrement)) // only fail if the two definitions do not match @@ -33,7 +36,7 @@ void KSGenValueSet::DiceValue(std::vector& aDicedValues) return; } tValueIncrement = fValueIncrement; - tValueCount = (fValueStop - fValueStart) / tValueIncrement; + tValueCount = (fValueStop - fValueStart) / tValueIncrement + 1; // last step included } for (unsigned int tIndex = 0; tIndex < tValueCount; tIndex++) { diff --git a/Kassiopeia/Geometry/CMakeLists.txt b/Kassiopeia/Geometry/CMakeLists.txt index 1e50b4ec7..7b4bc90a2 100644 --- a/Kassiopeia/Geometry/CMakeLists.txt +++ b/Kassiopeia/Geometry/CMakeLists.txt @@ -7,10 +7,10 @@ set( GEOMETRY_HEADER_BASENAMES KSGeoSide.h ) set( GEOMETRY_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Include + ${CMAKE_CURRENT_SOURCE_DIR}/Include ) foreach( BASENAME ${GEOMETRY_HEADER_BASENAMES} ) - list( APPEND GEOMETRY_HEADER_FILENAMES ${GEOMETRY_HEADER_PATH}/${BASENAME} ) + list( APPEND GEOMETRY_HEADER_FILENAMES ${GEOMETRY_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files @@ -22,42 +22,41 @@ set( GEOMETRY_SOURCE_BASENAMES KSGeoSide.cxx ) set( GEOMETRY_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source + ${CMAKE_CURRENT_SOURCE_DIR}/Source ) foreach( BASENAME ${GEOMETRY_SOURCE_BASENAMES} ) - list( APPEND GEOMETRY_SOURCE_FILENAMES ${GEOMETRY_SOURCE_PATH}/${BASENAME} ) + list( APPEND GEOMETRY_SOURCE_FILENAMES ${GEOMETRY_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) # data files set( GEOMETRY_DATA_BASENAMES ) set( GEOMETRY_DATA_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Data + ${CMAKE_CURRENT_SOURCE_DIR}/Data ) foreach( BASENAME ${GEOMETRY_DATA_BASENAMES} ) - list( APPEND GEOMETRY_DATA_FILENAMES ${GEOMETRY_DATA_PATH}/${BASENAME} ) + list( APPEND GEOMETRY_DATA_FILENAMES ${GEOMETRY_DATA_PATH}/${BASENAME} ) endforeach( BASENAME ) # config files set( GEOMETRY_CONFIG_BASENAMES ) set( GEOMETRY_CONFIG_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Config + ${CMAKE_CURRENT_SOURCE_DIR}/Config ) foreach( BASENAME ${GEOMETRY_CONFIG_BASENAMES} ) - list( APPEND GEOMETRY_CONFIG_FILENAMES ${GEOMETRY_CONFIG_PATH}/${BASENAME} ) + list( APPEND GEOMETRY_CONFIG_FILENAMES ${GEOMETRY_CONFIG_PATH}/${BASENAME} ) endforeach( BASENAME ) # library -kasper_internal_include_directories( ${GEOMETRY_HEADER_PATH} ) -add_library( KassiopeiaGeometry SHARED ${GEOMETRY_SOURCE_FILENAMES} ${GEOMETRY_HEADER_FILENAMES} ) -set_target_properties( KassiopeiaGeometry PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) +add_library( KassiopeiaGeometry SHARED + ${GEOMETRY_SOURCE_FILENAMES} ${GEOMETRY_HEADER_FILENAMES} ) +target_include_directories(KassiopeiaGeometry + PUBLIC $ $ ) target_link_libraries( KassiopeiaGeometry - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - KassiopeiaUtility - KassiopeiaObjects - KassiopeiaOperators + PUBLIC + KGeoBagCore + KassiopeiaOperators ) # install diff --git a/Kassiopeia/Interactions/CMakeLists.txt b/Kassiopeia/Interactions/CMakeLists.txt index 2907adc2b..5e1b9c364 100644 --- a/Kassiopeia/Interactions/CMakeLists.txt +++ b/Kassiopeia/Interactions/CMakeLists.txt @@ -46,10 +46,10 @@ set( INTERACTIONS_HEADER_BASENAMES KSIntDecayCalculatorFerencBBRTransition.h ) set( INTERACTIONS_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Include + ${CMAKE_CURRENT_SOURCE_DIR}/Include ) foreach( BASENAME ${INTERACTIONS_HEADER_BASENAMES} ) - list( APPEND INTERACTIONS_HEADER_FILENAMES ${INTERACTIONS_HEADER_PATH}/${BASENAME} ) + list( APPEND INTERACTIONS_HEADER_FILENAMES ${INTERACTIONS_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files @@ -99,10 +99,10 @@ set( INTERACTIONS_SOURCE_BASENAMES KSIntDecayCalculatorFerencBBRTransition.cxx ) set( INTERACTIONS_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source + ${CMAKE_CURRENT_SOURCE_DIR}/Source ) foreach( BASENAME ${INTERACTIONS_SOURCE_BASENAMES} ) - list( APPEND INTERACTIONS_SOURCE_FILENAMES ${INTERACTIONS_SOURCE_PATH}/${BASENAME} ) + list( APPEND INTERACTIONS_SOURCE_FILENAMES ${INTERACTIONS_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) # data files @@ -180,22 +180,20 @@ set( INTERACTIONS_DATA_BASENAMES PhotoAbsorbtion.txt ) set( INTERACTIONS_DATA_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Data + ${CMAKE_CURRENT_SOURCE_DIR}/Data ) foreach( BASENAME ${INTERACTIONS_DATA_BASENAMES} ) - list( APPEND INTERACTIONS_DATA_FILENAMES ${INTERACTIONS_DATA_PATH}/${BASENAME} ) + list( APPEND INTERACTIONS_DATA_FILENAMES ${INTERACTIONS_DATA_PATH}/${BASENAME} ) endforeach( BASENAME ) # library -kasper_internal_include_directories( ${INTERACTIONS_HEADER_PATH} ) -add_library( KassiopeiaInteractions SHARED ${INTERACTIONS_SOURCE_FILENAMES} ${INTERACTIONS_HEADER_FILENAMES} ) -set_target_properties( KassiopeiaInteractions PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) +add_library( KassiopeiaInteractions SHARED + ${INTERACTIONS_SOURCE_FILENAMES} ${INTERACTIONS_HEADER_FILENAMES} ) +target_include_directories(KassiopeiaInteractions + PUBLIC $ $ ) target_link_libraries( KassiopeiaInteractions - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - KassiopeiaUtility - KassiopeiaObjects - KassiopeiaOperators + PUBLIC + KassiopeiaOperators ) # install diff --git a/Kassiopeia/Interactions/Source/KSIntSurfaceSpecular.cxx b/Kassiopeia/Interactions/Source/KSIntSurfaceSpecular.cxx index 85f06a90f..f44fb7984 100644 --- a/Kassiopeia/Interactions/Source/KSIntSurfaceSpecular.cxx +++ b/Kassiopeia/Interactions/Source/KSIntSurfaceSpecular.cxx @@ -58,7 +58,7 @@ void KSIntSurfaceSpecular::ExecuteReflection(const KSParticle& anInitialParticle //prevent kinetic energy from going negative if (tKineticEnergy < 0.0) { - intmsg(eError) << "surface diffuse interaction named <" << GetName() + intmsg(eError) << "surface specular interaction named <" << GetName() << "> tried to give a particle a negative kinetic energy." << eom; return; } @@ -99,7 +99,7 @@ void KSIntSurfaceSpecular::ExecuteTransmission(const KSParticle& anInitialPartic //prevent kinetic energy from going negative if (tKineticEnergy < 0.0) { - intmsg(eError) << "surface diffuse interaction named <" << GetName() + intmsg(eError) << "surface specular interaction named <" << GetName() << "> tried to give a particle a negative kinetic energy." << eom; return; } diff --git a/Kassiopeia/KassiopeiaConfig.cmake.in b/Kassiopeia/KassiopeiaConfig.cmake.in new file mode 100644 index 000000000..a577134e4 --- /dev/null +++ b/Kassiopeia/KassiopeiaConfig.cmake.in @@ -0,0 +1,25 @@ +include(CMakeFindDependencyMacro) + +set(Kassiopeia_USE_BOOST @Kassiopeia_USE_BOOST@) +if(Kassiopeia_USE_BOOST) + find_dependency( Boost COMPONENTS ) +endif(Kassiopeia_USE_BOOST) + +set(Kassiopeia_USE_ROOT @Kassiopeia_USE_ROOT@) +if(Kassiopeia_USE_ROOT) + find_dependency( ROOT CONFIG ) +endif(Kassiopeia_USE_ROOT) + +set(Kassiopeia_USE_VTK @Kassiopeia_USE_VTK@) +if(Kassiopeia_USE_VTK) + find_dependency( VTK NO_MODULE ) +endif(Kassiopeia_USE_VTK) + +# Kasper dependencies +find_dependency( Kommon ) +find_dependency( KGeoBag ) +find_dependency( KEMField ) + +if(NOT TARGET @PROJECT_NAME@::@PROJECT_NAME@) + include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +endif() diff --git a/Kassiopeia/KassiopeiaConfigVersion.cmake.in b/Kassiopeia/KassiopeiaConfigVersion.cmake.in new file mode 100644 index 000000000..25f052f29 --- /dev/null +++ b/Kassiopeia/KassiopeiaConfigVersion.cmake.in @@ -0,0 +1,11 @@ +set(PACKAGE_VERSION "@MODULE_VERSION@") + +# Check whether the requested PACKAGE_FIND_VERSION is compatible +if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() diff --git a/Kassiopeia/Math/CMakeLists.txt b/Kassiopeia/Math/CMakeLists.txt index 982ab303e..ad62d47c0 100644 --- a/Kassiopeia/Math/CMakeLists.txt +++ b/Kassiopeia/Math/CMakeLists.txt @@ -17,28 +17,31 @@ set( MATH_HEADER_BASENAMES KSMathInterpolator.h ) set( MATH_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Include + ${CMAKE_CURRENT_SOURCE_DIR}/Include ) foreach( BASENAME ${MATH_HEADER_BASENAMES} ) - list( APPEND MATH_HEADER_FILENAMES ${MATH_HEADER_PATH}/${BASENAME} ) + list( APPEND MATH_HEADER_FILENAMES ${MATH_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files set( MATH_SOURCE_BASENAMES - KSMathMessage.cxx + KSMathMessage.cxx ) set( MATH_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source + ${CMAKE_CURRENT_SOURCE_DIR}/Source ) foreach( BASENAME ${MATH_SOURCE_BASENAMES} ) - list( APPEND MATH_SOURCE_FILENAMES ${MATH_SOURCE_PATH}/${BASENAME} ) + list( APPEND MATH_SOURCE_FILENAMES ${MATH_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) -# target -kasper_internal_include_directories( ${MATH_HEADER_PATH} ) -add_library( KassiopeiaMath SHARED ${MATH_SOURCE_FILENAMES} ${MATH_HEADER_FILENAMES} ) +# library +add_library( KassiopeiaMath SHARED + ${MATH_SOURCE_FILENAMES} ${MATH_HEADER_FILENAMES} ) +target_include_directories(KassiopeiaMath + PUBLIC $ $ ) target_link_libraries( KassiopeiaMath - ${Kommon_LIBRARIES} + PUBLIC + Kommon ) # install diff --git a/Kassiopeia/Modifiers/CMakeLists.txt b/Kassiopeia/Modifiers/CMakeLists.txt index 8b60bfb33..0f5260885 100644 --- a/Kassiopeia/Modifiers/CMakeLists.txt +++ b/Kassiopeia/Modifiers/CMakeLists.txt @@ -6,10 +6,10 @@ set( MODIFIERS_HEADER_BASENAMES KSModEventReport.h ) set( MODIFIERS_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Include + ${CMAKE_CURRENT_SOURCE_DIR}/Include ) foreach( BASENAME ${MODIFIERS_HEADER_BASENAMES} ) - list( APPEND MODIFIERS_HEADER_FILENAMES ${MODIFIERS_HEADER_PATH}/${BASENAME} ) + list( APPEND MODIFIERS_HEADER_FILENAMES ${MODIFIERS_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files @@ -20,34 +20,31 @@ set( MODIFIERS_SOURCE_BASENAMES KSModEventReport.cxx ) set( MODIFIERS_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source + ${CMAKE_CURRENT_SOURCE_DIR}/Source ) foreach( BASENAME ${MODIFIERS_SOURCE_BASENAMES} ) - list( APPEND MODIFIERS_SOURCE_FILENAMES ${MODIFIERS_SOURCE_PATH}/${BASENAME} ) + list( APPEND MODIFIERS_SOURCE_FILENAMES ${MODIFIERS_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) # data files set( MODIFIERS_DATA_BASENAMES ) set( MODIFIERS_DATA_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Data + ${CMAKE_CURRENT_SOURCE_DIR}/Data ) foreach( BASENAME ${MODIFIERS_DATA_BASENAMES} ) - list( APPEND MODIFIERS_DATA_FILENAMES ${MODIFIERS_DATA_PATH}/${BASENAME} ) + list( APPEND MODIFIERS_DATA_FILENAMES ${MODIFIERS_DATA_PATH}/${BASENAME} ) endforeach( BASENAME ) # library -kasper_internal_include_directories( ${MODIFIERS_HEADER_PATH} ) -add_library( KassiopeiaModifiers SHARED ${MODIFIERS_SOURCE_FILENAMES} ${MODIFIERS_HEADER_FILENAMES} ) -set_target_properties( KassiopeiaModifiers PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) +add_library( KassiopeiaModifiers SHARED + ${MODIFIERS_SOURCE_FILENAMES} ${MODIFIERS_HEADER_FILENAMES} ) +target_include_directories(KassiopeiaModifiers + PUBLIC $ $ ) target_link_libraries( KassiopeiaModifiers - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - KassiopeiaUtility - KassiopeiaObjects - KassiopeiaOperators - KassiopeiaTrajectories - KassiopeiaInteractions + PUBLIC + KassiopeiaTrajectories + KassiopeiaInteractions ) # install diff --git a/Kassiopeia/ModuleConfig.cmake.in b/Kassiopeia/ModuleConfig.cmake.in deleted file mode 100644 index e87fcab62..000000000 --- a/Kassiopeia/ModuleConfig.cmake.in +++ /dev/null @@ -1,24 +0,0 @@ -# $Id: ModuleConfig.cmake.in 12255 2012-03-16 09:26:20Z s_voec01 $ - -if(@PROJECT_NAME@_FOUND) - return() -endif() - -set(@PROJECT_NAME@_FOUND TRUE) - -# Update this section - -# The extra libraries one has to link against -set(@PROJECT_NAME@_DEPENDS @Kommon_LIBRARIES@ @Kommon_Vtk_LIBRARIES@ @ROOT_LIBRARIES@ @VTK_LIBRARIES@) -list(REMOVE_DUPLICATES @PROJECT_NAME@_DEPENDS) - -# End - -set(@PROJECT_NAME@_VERSION_MAJOR @MODULE_VERSION_MAJOR@) -set(@PROJECT_NAME@_VERSION_MINOR @MODULE_VERSION_MINOR@) -set(@PROJECT_NAME@_VERSION_PATCH @MODULE_VERSION_PATCH@) -set(@PROJECT_NAME@_VERSION @MODULE_VERSION@) - -set(@PROJECT_NAME@_INCLUDE_DIRS @MODULE_INCLUDE_DIRS@) -set(@PROJECT_NAME@_LIBRARIES @MODULE_TARGETS@) -mark_as_advanced(@PROJECT_NAME@_DIR) diff --git a/Kassiopeia/ModuleConfigInstalled.cmake.in b/Kassiopeia/ModuleConfigInstalled.cmake.in deleted file mode 100644 index d315d4182..000000000 --- a/Kassiopeia/ModuleConfigInstalled.cmake.in +++ /dev/null @@ -1,30 +0,0 @@ -# $Id: ModuleConfig.cmake.in 11925 2012-01-23 14:54:05Z s_voec01 $ - -if(@PROJECT_NAME@_FOUND) - return() -endif() - -set(@PROJECT_NAME@_FOUND TRUE) - -# Update this section - -set(@PROJECT_NAME@_DEPENDS @Kommon_LIBRARIES@ @Kommon_Vtk_LIBRARIES@ @ROOT_LIBRARIES@ @VTK_LIBRARIES@) -list(REMOVE_DUPLICATES @PROJECT_NAME@_DEPENDS) - -# End - -set(@PROJECT_NAME@_VERSION_MAJOR @MODULE_VERSION_MAJOR@) -set(@PROJECT_NAME@_VERSION_MINOR @MODULE_VERSION_MINOR@) -set(@PROJECT_NAME@_VERSION_PATCH @MODULE_VERSION_PATCH@) -set(@PROJECT_NAME@_VERSION @MODULE_VERSION@) - -get_filename_component(MODULE_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) -if(EXISTS "${MODULE_CMAKE_DIR}/ModuleTargets.cmake") - include("${MODULE_CMAKE_DIR}/ModuleTargets.cmake") -elseif(NOT KASPER_TARGETS_INCLUDED) - include("${MODULE_CMAKE_DIR}/../Kasper/KasperTargets.cmake") - set(KASPER_TARGETS_INCLUDED TRUE) -endif() - -set(@PROJECT_NAME@_INCLUDE_DIRS @INSTALLED_INCLUDE_DIRS@) -set(@PROJECT_NAME@_LIBRARIES @MODULE_TARGETS@) diff --git a/Kassiopeia/Navigators/CMakeLists.txt b/Kassiopeia/Navigators/CMakeLists.txt index 734ca6963..4ad1c37d2 100644 --- a/Kassiopeia/Navigators/CMakeLists.txt +++ b/Kassiopeia/Navigators/CMakeLists.txt @@ -11,10 +11,10 @@ set( NAVIGATORS_HEADER_BASENAMES KSNavOctreeData.h ) set( NAVIGATORS_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Include + ${CMAKE_CURRENT_SOURCE_DIR}/Include ) foreach( BASENAME ${NAVIGATORS_HEADER_BASENAMES} ) - list( APPEND NAVIGATORS_HEADER_FILENAMES ${NAVIGATORS_HEADER_PATH}/${BASENAME} ) + list( APPEND NAVIGATORS_HEADER_FILENAMES ${NAVIGATORS_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files @@ -25,50 +25,48 @@ set( NAVIGATORS_SOURCE_BASENAMES KSNavMeshedSpace.cxx ) set( NAVIGATORS_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source + ${CMAKE_CURRENT_SOURCE_DIR}/Source ) foreach( BASENAME ${NAVIGATORS_SOURCE_BASENAMES} ) - list( APPEND NAVIGATORS_SOURCE_FILENAMES ${NAVIGATORS_SOURCE_PATH}/${BASENAME} ) + list( APPEND NAVIGATORS_SOURCE_FILENAMES ${NAVIGATORS_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) # data files set( NAVIGATORS_DATA_BASENAMES ) set( NAVIGATORS_DATA_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Data + ${CMAKE_CURRENT_SOURCE_DIR}/Data ) foreach( BASENAME ${NAVIGATORS_DATA_BASENAMES} ) - list( APPEND NAVIGATORS_DATA_FILENAMES ${NAVIGATORS_DATA_PATH}/${BASENAME} ) + list( APPEND NAVIGATORS_DATA_FILENAMES ${NAVIGATORS_DATA_PATH}/${BASENAME} ) endforeach( BASENAME ) # config files set( NAVIGATORS_CONFIG_BASENAMES ) set( NAVIGATORS_CONFIG_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Config + ${CMAKE_CURRENT_SOURCE_DIR}/Config ) foreach( BASENAME ${NAVIGATORS_CONFIG_BASENAMES} ) - list( APPEND NAVIGATORS_CONFIG_FILENAMES ${NAVIGATORS_CONFIG_PATH}/${BASENAME} ) + list( APPEND NAVIGATORS_CONFIG_FILENAMES ${NAVIGATORS_CONFIG_PATH}/${BASENAME} ) endforeach( BASENAME ) # library -kasper_internal_include_directories( ${NAVIGATORS_HEADER_PATH} ) -add_library( KassiopeiaNavigators SHARED ${NAVIGATORS_SOURCE_FILENAMES} ${NAVIGATORS_HEADER_FILENAMES} ) -set_target_properties( KassiopeiaNavigators PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) +add_library( KassiopeiaNavigators SHARED + ${NAVIGATORS_SOURCE_FILENAMES} ${NAVIGATORS_HEADER_FILENAMES} ) +target_include_directories(KassiopeiaNavigators + PUBLIC $ $ ) target_link_libraries( KassiopeiaNavigators - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - KEMFileManipulation - KEMHashGenerator - KassiopeiaUtility - KassiopeiaObjects - KassiopeiaOperators - KassiopeiaGeometry + PUBLIC + KassiopeiaOperators + KassiopeiaGeometry + KEMFileManipulation + KGeoBagMesh ) # install kasper_install_headers( ${NAVIGATORS_HEADER_FILENAMES} ) +kasper_install_libraries( KassiopeiaNavigators ) kasper_install_data( ${NAVIGATORS_DATA_FILENAMES} ) kasper_install_config_subdir( Complete ${NAVIGATORS_CONFIG_FILENAMES} ) -kasper_install_libraries( KassiopeiaNavigators ) diff --git a/Kassiopeia/Navigators/Source/KSNavMeshedSpace.cxx b/Kassiopeia/Navigators/Source/KSNavMeshedSpace.cxx index 09c7f5fe2..3d294a831 100644 --- a/Kassiopeia/Navigators/Source/KSNavMeshedSpace.cxx +++ b/Kassiopeia/Navigators/Source/KSNavMeshedSpace.cxx @@ -902,7 +902,6 @@ void KSNavMeshedSpace::ExecuteNavigation(const KSParticle& aNavigationParticle, if (fSideEntity != nullptr) { navmsg(eNormal) << " side <" << fSideEntity->GetName() << "> was crossed" << eom; aFinalParticle = aNavigationParticle; - ; aFinalParticle.SetLabel(GetName()); aFinalParticle.AddLabel(fSideEntity->GetName()); aFinalParticle.AddLabel("crossed"); @@ -1149,6 +1148,9 @@ void KSNavMeshedSpace::StopNavigation(KSParticle& aParticle, KSSpace* aRoot) double KSNavMeshedSpace::SolveForTime(double distance, double t, double v1, double v2) const { + if (v1 == v2) + return 0.; + //solving for the time to travel the specified distance //along a straight line path with initial velocity //v1 and final velocity v2, assuming constant acceleration diff --git a/Kassiopeia/Objects/CMakeLists.txt b/Kassiopeia/Objects/CMakeLists.txt index f62c7d970..3e6636e23 100644 --- a/Kassiopeia/Objects/CMakeLists.txt +++ b/Kassiopeia/Objects/CMakeLists.txt @@ -1,70 +1,68 @@ # header files set( OBJECTS_HEADER_BASENAMES - KSObjectsMessage.h - KSObject.h - KSCommand.h - KSCommandGroup.h - KSComponent.h - KSComponentGroup.h - KSDictionary.h - KSCommandMember.h - KSComponentMember.h - KSComponentValue.h - KSComponentDelta.h - KSComponentIntegral.h - KSComponentMaximum.h - KSComponentMinimum.h - KSComponentMaximumAt.h - KSComponentMinimumAt.h - KSComponentTemplate.h + KSObjectsMessage.h + KSObject.h + KSCommand.h + KSCommandGroup.h + KSComponent.h + KSComponentGroup.h + KSDictionary.h + KSCommandMember.h + KSComponentMember.h + KSComponentValue.h + KSComponentDelta.h + KSComponentIntegral.h + KSComponentMaximum.h + KSComponentMinimum.h + KSComponentMaximumAt.h + KSComponentMinimumAt.h + KSComponentTemplate.h ) if( Kassiopeia_USE_ROOT ) list( APPEND OBJECTS_HEADER_BASENAMES - KSComponentMath.h + KSComponentMath.h ) endif( Kassiopeia_USE_ROOT ) set( OBJECTS_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Include + ${CMAKE_CURRENT_SOURCE_DIR}/Include ) foreach( BASENAME ${OBJECTS_HEADER_BASENAMES} ) - list( APPEND OBJECTS_HEADER_FILENAMES ${OBJECTS_HEADER_PATH}/${BASENAME} ) + list( APPEND OBJECTS_HEADER_FILENAMES ${OBJECTS_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files set( OBJECTS_SOURCE_BASENAMES - KSObjectsMessage.cxx - KSObject.cxx - KSCommand.cxx - KSCommandGroup.cxx - KSComponent.cxx - KSComponentGroup.cxx - KSDictionary.cxx + KSObjectsMessage.cxx + KSObject.cxx + KSCommand.cxx + KSCommandGroup.cxx + KSComponent.cxx + KSComponentGroup.cxx + KSDictionary.cxx ) set( OBJECTS_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source + ${CMAKE_CURRENT_SOURCE_DIR}/Source ) foreach( BASENAME ${OBJECTS_SOURCE_BASENAMES} ) - list( APPEND OBJECTS_SOURCE_FILENAMES ${OBJECTS_SOURCE_PATH}/${BASENAME} ) + list( APPEND OBJECTS_SOURCE_FILENAMES ${OBJECTS_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) # library -kasper_internal_include_directories( ${OBJECTS_HEADER_PATH} ) -add_library( KassiopeiaObjects SHARED ${OBJECTS_SOURCE_FILENAMES} ${OBJECTS_HEADER_FILENAMES} ) -set_target_properties( KassiopeiaObjects PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) +add_library( KassiopeiaObjects SHARED + ${OBJECTS_SOURCE_FILENAMES} ${OBJECTS_HEADER_FILENAMES} ) +target_include_directories(KassiopeiaObjects + PUBLIC $ $ ) target_link_libraries( KassiopeiaObjects - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - KassiopeiaUtility + PUBLIC + KassiopeiaUtility ) # install kasper_install_headers( ${OBJECTS_HEADER_FILENAMES} ) kasper_install_libraries( KassiopeiaObjects ) - - diff --git a/Kassiopeia/Operators/CMakeLists.txt b/Kassiopeia/Operators/CMakeLists.txt index 43e678063..02b729abd 100644 --- a/Kassiopeia/Operators/CMakeLists.txt +++ b/Kassiopeia/Operators/CMakeLists.txt @@ -1,72 +1,72 @@ # header files set( OPERATORS_HEADER_BASENAMES - KSOperatorsMessage.h - KSParticle.h - KSParticleFactory.h - KSMagneticField.h - KSElectricField.h - KSGenerator.h - KSTrajectory.h - KSSpace.h - KSSpaceInteraction.h - KSSpaceNavigator.h - KSSurface.h - KSSurfaceInteraction.h - KSSurfaceNavigator.h + KSOperatorsMessage.h + KSParticle.h + KSParticleFactory.h + KSMagneticField.h + KSElectricField.h + KSGenerator.h + KSTrajectory.h + KSSpace.h + KSSpaceInteraction.h + KSSpaceNavigator.h + KSSurface.h + KSSurfaceInteraction.h + KSSurfaceNavigator.h KSSide.h - KSStepModifier.h + KSStepModifier.h KSTrackModifier.h KSEventModifier.h KSRunModifier.h - KSTerminator.h - KSWriter.h + KSTerminator.h + KSWriter.h ) set( OPERATORS_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Include + ${CMAKE_CURRENT_SOURCE_DIR}/Include ) foreach( BASENAME ${OPERATORS_HEADER_BASENAMES} ) - list( APPEND OPERATORS_HEADER_FILENAMES ${OPERATORS_HEADER_PATH}/${BASENAME} ) + list( APPEND OPERATORS_HEADER_FILENAMES ${OPERATORS_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files set( OPERATORS_SOURCE_BASENAMES - KSOperatorsMessage.cxx - KSParticle.cxx - KSParticleFactory.cxx - KSMagneticField.cxx - KSElectricField.cxx - KSGenerator.cxx - KSTrajectory.cxx - KSSpace.cxx + KSOperatorsMessage.cxx + KSParticle.cxx + KSParticleFactory.cxx + KSMagneticField.cxx + KSElectricField.cxx + KSGenerator.cxx + KSTrajectory.cxx + KSSpace.cxx KSSpaceInteraction.cxx KSSpaceNavigator.cxx KSSurface.cxx - KSSurfaceInteraction.cxx - KSSurfaceNavigator.cxx + KSSurfaceInteraction.cxx + KSSurfaceNavigator.cxx KSSide.cxx - KSStepModifier.cxx + KSStepModifier.cxx KSTrackModifier.cxx KSEventModifier.cxx KSRunModifier.cxx - KSTerminator.cxx - KSWriter.cxx + KSTerminator.cxx + KSWriter.cxx ) set( OPERATORS_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source + ${CMAKE_CURRENT_SOURCE_DIR}/Source ) foreach( BASENAME ${OPERATORS_SOURCE_BASENAMES} ) - list( APPEND OPERATORS_SOURCE_FILENAMES ${OPERATORS_SOURCE_PATH}/${BASENAME} ) + list( APPEND OPERATORS_SOURCE_FILENAMES ${OPERATORS_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) # library -kasper_internal_include_directories( ${OPERATORS_HEADER_PATH} ) -add_library( KassiopeiaOperators SHARED ${OPERATORS_SOURCE_FILENAMES} ${OPERATORS_HEADER_FILENAMES} ) -set_target_properties( KassiopeiaOperators PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) +add_library( KassiopeiaOperators SHARED + ${OPERATORS_SOURCE_FILENAMES} ${OPERATORS_HEADER_FILENAMES} ) +target_include_directories(KassiopeiaOperators + PUBLIC $ $ ) target_link_libraries( KassiopeiaOperators - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - KassiopeiaUtility - KassiopeiaObjects + PUBLIC + KGeoBagMath + KassiopeiaObjects ) # install diff --git a/Kassiopeia/Operators/Source/KSParticle.cxx b/Kassiopeia/Operators/Source/KSParticle.cxx index 64283fee1..77bfc3a82 100644 --- a/Kassiopeia/Operators/Source/KSParticle.cxx +++ b/Kassiopeia/Operators/Source/KSParticle.cxx @@ -285,6 +285,7 @@ void KSParticle::Print() const { oprmsg(eInfo); oprmsg << "KSParticle state: [" << fIndexNumber << "]" << ret; + oprmsg << " label: " << fLabel << ret; oprmsg << " id: " << fPID << ret; oprmsg << " string id: " << fStringID << ret; oprmsg << " mass: " << fMass << ret; @@ -330,8 +331,8 @@ bool KSParticle::IsValid() const return false; if (!isfinite(fMomentum.X()) || !isfinite(fMomentum.Y()) || !isfinite(fMomentum.Z())) return false; - if (!isfinite(fSpin0) || !isfinite(fSpin.X()) || !isfinite(fSpin.Y()) || !isfinite(fSpin.Z())) - return false; + //if (!isfinite(fSpin0) || !isfinite(fSpin.X()) || !isfinite(fSpin.Y()) || !isfinite(fSpin.Z())) + // return false; /** require E > 0 for tracking */ if (fMomentum.MagnitudeSquared() <= std::numeric_limits::min()) return false; @@ -2330,4 +2331,8 @@ STATICINT sKSKThreeVectorDict = KSDictionary::AddComponent(&KThreeVector::PolarAngle, "polar_angle") + KSDictionary::AddComponent(&KThreeVector::AzimuthalAngle, "azimuthal_angle"); +STATICINT sKSKThreeMatrixDict = + KSDictionary::AddComponent(&KThreeMatrix::Determinant, "determinant") + + KSDictionary::AddComponent(&KThreeMatrix::Trace, "trace"); + } /* namespace Kassiopeia */ diff --git a/Kassiopeia/Operators/Source/KSParticleFactory.cxx b/Kassiopeia/Operators/Source/KSParticleFactory.cxx index 0ad076b87..e48e7e34b 100644 --- a/Kassiopeia/Operators/Source/KSParticleFactory.cxx +++ b/Kassiopeia/Operators/Source/KSParticleFactory.cxx @@ -139,7 +139,7 @@ KSElectricField* KSParticleFactory::GetElectricField() // A "ghost" particle STATICINT sGhostDefinition = KSParticleFactory::GetInstance().Define( - 0, "ghost", {}, std::numeric_limits::min(), 0., 0., 0.); // needs to have non-zero mass + 0, "ghost", {}, 1e-123, 0., 0., 0.); // needs to have non-zero mass, but too small energy breaks tracking //electron STATICINT sElectronDefinition = KSParticleFactory::GetInstance().Define( diff --git a/Kassiopeia/Python/CMakeLists.txt b/Kassiopeia/Python/CMakeLists.txt index 146fb8d05..b30d709ef 100644 --- a/Kassiopeia/Python/CMakeLists.txt +++ b/Kassiopeia/Python/CMakeLists.txt @@ -1,7 +1,7 @@ # $Id$ set( KASSIOPEIA_PYTHON_SOURCES - KassiopeiaReader.py + KassiopeiaReader.py ) install(FILES ${KASSIOPEIA_PYTHON_SOURCES} ${KASSIOPEIA_PYTHON_HEADERS} DESTINATION ${${PROJECT_NAME}_LIB_INSTALL_DIR}/python) diff --git a/Kassiopeia/Python/Examples/QuadrupoleTrapAnalysis.py b/Kassiopeia/Python/Examples/QuadrupoleTrapAnalysis.py index 4fb309bb5..6407e1dd1 100644 --- a/Kassiopeia/Python/Examples/QuadrupoleTrapAnalysis.py +++ b/Kassiopeia/Python/Examples/QuadrupoleTrapAnalysis.py @@ -13,58 +13,61 @@ # create reader instance reader = KassiopeiaReader.Iterator(sys.argv[1]) -# retrieve list of valid step ranges -step_presence = reader.getTree('component_step_cell_PRESENCE') -step_valid = zip(*[step_presence['INDEX'], step_presence['LENGTH']]) - -# retrieve list of step ranges per track -track_step_index = list(zip(*[reader.getTracks('FIRST_STEP_INDEX'), reader.getTracks('LAST_STEP_INDEX')])) -#print("#tracks:", len(track_step_index)) - # load step-data tree reader.loadTree('component_step_cell') +#print("#tracks:", len(reader.getTracks('TRACK_INDEX'))) #print('#steps: ', len(reader)) #print('fields: ', dir(reader)) # select a single output field reader.select('orbital_magnetic_moment') -# iterate over track indices -for first_step_index, last_step_index in track_step_index: +# retrieve list of valid step ranges +step_presence = reader.getTree('component_step_cell_PRESENCE') +step_valid = zip(*[step_presence['INDEX'], step_presence['LENGTH']]) - max_moment = -np.inf - min_moment = np.inf +# create step iterator +step = iter(reader) +#print('fields: ', dir(step)) - # iterate over steps in given range - for step in iter(reader): +# iterate over track indices +for track_index in reader.getTracks('TRACK_INDEX'): + + # retrieve index of first/last step for current track + first_step_index = reader.getTracks('FIRST_STEP_INDEX')[track_index] + last_step_index = reader.getTracks('LAST_STEP_INDEX')[track_index] - step_index = reader.iev - 1 + # adjust first/last step range to include only valid entries + for first_valid,valid_length in step_valid: + last_valid = first_valid + valid_length - 1 + if first_valid >= first_step_index: + first_step_index = first_valid + if last_valid < last_step_index: + last_step_index = last_valid + break - # advance iterator to first step in this track - if step_index < first_step_index: - continue + #print("track #{} valid interval: {} .. {}".format(track_index, first_step_index, last_step_index)) - # only process steps in valid range within this track - for first_valid,valid_length in step_valid: + # advance iterator to first step + while reader.iev < first_step_index: + item = next(step) - last_valid = first_valid + valid_length - 1 - if step_index >= first_valid and step_index <= last_valid: + max_moment = -float('Inf') + min_moment = float('Inf') - moment = float(step.orbital_magnetic_moment) - if moment > max_moment: - max_moment = moment - if moment < min_moment: - min_moment = moment + # iterate over steps in given range + while reader.iev <= last_step_index: - if first_valid > first_step_index: - break + # advance step iterator + item = next(step) - # stop iteration at the end of this track - if step_index >= last_step_index: - break + moment = float(item.orbital_magnetic_moment) + if moment > max_moment: + max_moment = moment + if moment < min_moment: + min_moment = moment # calculate result for current track deviation = 2.0 * (max_moment - min_moment) / (max_moment + min_moment) print("extrema for track <{:g}>".format(deviation)) - break diff --git a/Kassiopeia/README b/Kassiopeia/README index 2858af0da..83129e3a4 100644 --- a/Kassiopeia/README +++ b/Kassiopeia/README @@ -1,36 +1,20 @@ -Kassiopeia 3.2 - a tracking simulation package from the KATRIN collaboration +Kassiopeia - a tracking simulation package from the KATRIN collaboration Licensing and Warranty: - The KATRIN collaboration and the developers of Kassiopeia make no assurance - whatsoever as to the merchantability or fitness of the Kassiopeia package - for any particular purpose. The code is provided on an as-is basis only. + See https://katrin-experiment.github.io/Kassiopeia/license.html Authors: - < use list from paper > + See https://katrin-experiment.github.io/Kassiopeia/authors.html User's Guide: - An introductory user's guide in PDF form is available at: - < doesn't exist yet! > - The User's Guide is meant to show new users how to set up and run their - first few simulations, and broadly explains how Kassiopeia works. + Documentation can be found in the user's guide available at: + https://katrin-experiment.github.io/Kassiopeia/ -Developer's Guide: - A developer's guide in PDF form is available at: - < doesn't exist yet > - The Developer's Guide is a detailed explanation of how Kassiopeia is - is structured, and is aimed at programmers wishing to add their own modules - to extend the Kassiopeia framework. - - -Wiki: - A wiki page for Kassiopeia is maintained at: - < wiki link here > - Bugs: In the surely unlikely event that you find a bug, it may be submitted to the Kassiopeia bug tracker at: - < bug tracker link here > + https://github.com/KATRIN-Experiment/Kassiopeia/issues Reference: - To cite Kassiopeia, please see the paper at: - < hahahaha > \ No newline at end of file + To cite the use of and/or data produced with the assistance of Kassiopeia or its associated libraries (KGeoBag, KEMField, or Kommon), please refer to the paper: + D. Furse et al. (2017) New J. Phys. 19 053012: “Kassiopeia: A Modern, Extensible C++ Particle Tracking Package” (doi:10.1088/1367-2630/aa6950) diff --git a/Kassiopeia/Readers/CMakeLists.txt b/Kassiopeia/Readers/CMakeLists.txt index 6a616bdc0..f01419052 100644 --- a/Kassiopeia/Readers/CMakeLists.txt +++ b/Kassiopeia/Readers/CMakeLists.txt @@ -1,79 +1,77 @@ # header files set( READERS_HEADER_BASENAMES - KSReadersMessage.h + KSReadersMessage.h - KSReadValue.h - KSReadSet.h - KSReadIterator.h - KSReadFile.h + KSReadValue.h + KSReadSet.h + KSReadIterator.h + KSReadFile.h ) if( Kassiopeia_USE_ROOT ) - list( APPEND READERS_HEADER_BASENAMES - KSReadIteratorROOT.h - KSReadRunROOT.h - KSReadEventROOT.h - KSReadTrackROOT.h - KSReadStepROOT.h - KSReadObjectROOT.h - KSReadFileROOT.h - ) + list( APPEND READERS_HEADER_BASENAMES + KSReadIteratorROOT.h + KSReadRunROOT.h + KSReadEventROOT.h + KSReadTrackROOT.h + KSReadStepROOT.h + KSReadObjectROOT.h + KSReadFileROOT.h + ) endif( Kassiopeia_USE_ROOT ) set( READERS_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Include + ${CMAKE_CURRENT_SOURCE_DIR}/Include ) foreach( BASENAME ${READERS_HEADER_BASENAMES} ) - list( APPEND READERS_HEADER_FILENAMES ${READERS_HEADER_PATH}/${BASENAME} ) + list( APPEND READERS_HEADER_FILENAMES ${READERS_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files set( READERS_SOURCE_BASENAMES - KSReadersMessage.cxx - KSReadIterator.cxx - KSReadFile.cxx + KSReadersMessage.cxx + KSReadIterator.cxx + KSReadFile.cxx ) if( Kassiopeia_USE_ROOT ) - list( APPEND READERS_SOURCE_BASENAMES - KSReadIteratorROOT.cxx - KSReadRunROOT.cxx - KSReadEventROOT.cxx - KSReadTrackROOT.cxx - KSReadStepROOT.cxx - KSReadObjectROOT.cxx - KSReadFileROOT.cxx + list( APPEND READERS_SOURCE_BASENAMES + KSReadIteratorROOT.cxx + KSReadRunROOT.cxx + KSReadEventROOT.cxx + KSReadTrackROOT.cxx + KSReadStepROOT.cxx + KSReadObjectROOT.cxx + KSReadFileROOT.cxx ) endif( Kassiopeia_USE_ROOT ) set( READERS_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source + ${CMAKE_CURRENT_SOURCE_DIR}/Source ) foreach( BASENAME ${READERS_SOURCE_BASENAMES} ) - list( APPEND READERS_SOURCE_FILENAMES ${READERS_SOURCE_PATH}/${BASENAME} ) + list( APPEND READERS_SOURCE_FILENAMES ${READERS_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) # data files set( READERS_DATA_BASENAMES ) set( READERS_DATA_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Data + ${CMAKE_CURRENT_SOURCE_DIR}/Data ) foreach( BASENAME ${READERS_DATA_BASENAMES} ) - list( APPEND READERS_DATA_FILENAMES ${READERS_DATA_PATH}/${BASENAME} ) + list( APPEND READERS_DATA_FILENAMES ${READERS_DATA_PATH}/${BASENAME} ) endforeach( BASENAME ) # library -kasper_internal_include_directories( ${READERS_HEADER_PATH} ) -add_library( KassiopeiaReaders SHARED ${READERS_SOURCE_FILENAMES} ${READERS_HEADER_FILENAMES} ) -set_target_properties( KassiopeiaReaders PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) +add_library( KassiopeiaReaders SHARED + ${READERS_SOURCE_FILENAMES} ${READERS_HEADER_FILENAMES} ) +target_include_directories(KassiopeiaReaders + PUBLIC $ $ ) target_link_libraries( KassiopeiaReaders - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - KassiopeiaUtility - KassiopeiaObjects - KassiopeiaOperators - ${ROOT_LIBRARIES} + PUBLIC + KassiopeiaOperators + ROOT::Tree ) # install diff --git a/Kassiopeia/Readers/Include/KSReadIteratorROOT.h b/Kassiopeia/Readers/Include/KSReadIteratorROOT.h index 3b0fcf667..79a6f047f 100644 --- a/Kassiopeia/Readers/Include/KSReadIteratorROOT.h +++ b/Kassiopeia/Readers/Include/KSReadIteratorROOT.h @@ -21,6 +21,8 @@ class KSReadIteratorROOT : public KSDoubleSet, public KSThreeVectorSet, public KSTwoVectorSet, + public KSThreeMatrixSet, + public KSTwoMatrixSet, public KSStringSet { private: diff --git a/Kassiopeia/Readers/Include/KSReadObjectROOT.h b/Kassiopeia/Readers/Include/KSReadObjectROOT.h index 3759b7658..3e6bef130 100644 --- a/Kassiopeia/Readers/Include/KSReadObjectROOT.h +++ b/Kassiopeia/Readers/Include/KSReadObjectROOT.h @@ -23,6 +23,8 @@ class KSReadObjectROOT : public KSDoubleSet, public KSThreeVectorSet, public KSTwoVectorSet, + public KSThreeMatrixSet, + public KSTwoMatrixSet, public KSStringSet { public: diff --git a/Kassiopeia/Readers/Include/KSReadSet.h b/Kassiopeia/Readers/Include/KSReadSet.h index fa2db4c14..1398d4eff 100644 --- a/Kassiopeia/Readers/Include/KSReadSet.h +++ b/Kassiopeia/Readers/Include/KSReadSet.h @@ -76,6 +76,8 @@ using KSFloatSet = KSReadSet>; using KSDoubleSet = KSReadSet>; using KSThreeVectorSet = KSReadSet>; using KSTwoVectorSet = KSReadSet>; +using KSThreeMatrixSet = KSReadSet>; +using KSTwoMatrixSet = KSReadSet>; using KSStringSet = KSReadSet>; } // namespace Kassiopeia diff --git a/Kassiopeia/Readers/Include/KSReadValue.h b/Kassiopeia/Readers/Include/KSReadValue.h index d4a3a8078..ef583c9ea 100644 --- a/Kassiopeia/Readers/Include/KSReadValue.h +++ b/Kassiopeia/Readers/Include/KSReadValue.h @@ -4,6 +4,8 @@ #include "KSReadersMessage.h" #include "KThreeVector.hh" #include "KTwoVector.hh" +#include "KThreeMatrix.hh" +#include "KTwoMatrix.hh" namespace Kassiopeia { @@ -172,6 +174,8 @@ using KSFloat = KSReadValue; using KSDouble = KSReadValue; using KSThreeVector = KSReadValue; using KSTwoVector = KSReadValue; +using KSThreeMatrix = KSReadValue; +using KSTwoMatrix = KSReadValue; using KSString = KSReadValue; template<> const KSBool KSBool::sZero; @@ -202,7 +206,12 @@ template<> const KSThreeVector KSThreeVector::sZero; template<> const KSTwoVector KSTwoVector::sZero; +template<> const KSThreeMatrix KSThreeMatrix::sZero; + +template<> const KSTwoMatrix KSTwoMatrix::sZero; + template<> const KSString KSString::sZero; + } // namespace Kassiopeia #endif diff --git a/Kassiopeia/Readers/Source/KSReadIterator.cxx b/Kassiopeia/Readers/Source/KSReadIterator.cxx index 134190b05..eb91bab55 100644 --- a/Kassiopeia/Readers/Source/KSReadIterator.cxx +++ b/Kassiopeia/Readers/Source/KSReadIterator.cxx @@ -27,9 +27,13 @@ template<> const KSFloat KSFloat::sZero(0.); template<> const KSDouble KSDouble::sZero(0); -template<> const KSThreeVector KSThreeVector::sZero(KGeoBag::KThreeVector(0., 0., 0.)); +template<> const KSThreeVector KSThreeVector::sZero(KGeoBag::KThreeVector::sZero); -template<> const KSTwoVector KSTwoVector::sZero(KGeoBag::KTwoVector(0., 0.)); +template<> const KSTwoVector KSTwoVector::sZero(KGeoBag::KTwoVector::sZero); + +template<> const KSThreeMatrix KSThreeMatrix::sZero(KGeoBag::KThreeMatrix::sZero); + +template<> const KSTwoMatrix KSTwoMatrix::sZero(KGeoBag::KTwoMatrix::sZero); template<> const KSString KSString::sZero(std::string("")); diff --git a/Kassiopeia/Readers/Source/KSReadObjectROOT.cxx b/Kassiopeia/Readers/Source/KSReadObjectROOT.cxx index 3ff665fff..f08815c00 100644 --- a/Kassiopeia/Readers/Source/KSReadObjectROOT.cxx +++ b/Kassiopeia/Readers/Source/KSReadObjectROOT.cxx @@ -68,7 +68,7 @@ KSReadObjectROOT::KSReadObjectROOT(TTree* aStructureTree, TTree* aPresenceTree, fData->SetBranchAddress(tLabel.c_str(), Add(tLabel).Pointer()); continue; } - if (tType == string("long long")) { + if (tType == string("long long") || tType == string("long_long")) { fData->SetBranchAddress(tLabel.c_str(), Add(tLabel).Pointer()); continue; } @@ -94,10 +94,32 @@ KSReadObjectROOT::KSReadObjectROOT(TTree* aStructureTree, TTree* aPresenceTree, continue; } if (tType == string("three_vector")) { - auto& tTwoVector = Add(tLabel); - fData->SetBranchAddress((tLabel + string("_x")).c_str(), &(tTwoVector.Value().X())); - fData->SetBranchAddress((tLabel + string("_y")).c_str(), &(tTwoVector.Value().Y())); - fData->SetBranchAddress((tLabel + string("_z")).c_str(), &(tTwoVector.Value().Z())); + auto& tThreeVector = Add(tLabel); + fData->SetBranchAddress((tLabel + string("_x")).c_str(), &(tThreeVector.Value().X())); + fData->SetBranchAddress((tLabel + string("_y")).c_str(), &(tThreeVector.Value().Y())); + fData->SetBranchAddress((tLabel + string("_z")).c_str(), &(tThreeVector.Value().Z())); + continue; + } + + if (tType == string("two_matrix")) { + auto& tTwoMatrix = Add(tLabel); + fData->SetBranchAddress((tLabel + string("_xx")).c_str(), &(tTwoMatrix.Value().At(0,0))); + fData->SetBranchAddress((tLabel + string("_xy")).c_str(), &(tTwoMatrix.Value().At(0,1))); + fData->SetBranchAddress((tLabel + string("_yx")).c_str(), &(tTwoMatrix.Value().At(1,0))); + fData->SetBranchAddress((tLabel + string("_yy")).c_str(), &(tTwoMatrix.Value().At(1,1))); + continue; + } + if (tType == string("three_matrix")) { + auto& tThreeMatrix = Add(tLabel); + fData->SetBranchAddress((tLabel + string("_xx")).c_str(), &(tThreeMatrix.Value().At(0,0))); + fData->SetBranchAddress((tLabel + string("_xy")).c_str(), &(tThreeMatrix.Value().At(0,1))); + fData->SetBranchAddress((tLabel + string("_xz")).c_str(), &(tThreeMatrix.Value().At(0,2))); + fData->SetBranchAddress((tLabel + string("_yx")).c_str(), &(tThreeMatrix.Value().At(1,0))); + fData->SetBranchAddress((tLabel + string("_yy")).c_str(), &(tThreeMatrix.Value().At(1,1))); + fData->SetBranchAddress((tLabel + string("_yz")).c_str(), &(tThreeMatrix.Value().At(1,2))); + fData->SetBranchAddress((tLabel + string("_zx")).c_str(), &(tThreeMatrix.Value().At(2,0))); + fData->SetBranchAddress((tLabel + string("_zy")).c_str(), &(tThreeMatrix.Value().At(2,1))); + fData->SetBranchAddress((tLabel + string("_zz")).c_str(), &(tThreeMatrix.Value().At(2,2))); continue; } diff --git a/Kassiopeia/Simulation/CMakeLists.txt b/Kassiopeia/Simulation/CMakeLists.txt index 863bd22c0..43518f1d3 100644 --- a/Kassiopeia/Simulation/CMakeLists.txt +++ b/Kassiopeia/Simulation/CMakeLists.txt @@ -5,11 +5,11 @@ set( SIMULATION_HEADER_BASENAMES KSEventMessage.h KSTrackMessage.h KSStepMessage.h - KSSimulation.h - KSRun.h - KSEvent.h - KSTrack.h - KSStep.h + KSSimulation.h + KSRun.h + KSEvent.h + KSTrack.h + KSStep.h KSRootElectricField.h KSRootMagneticField.h KSRootStepModifier.h @@ -28,10 +28,10 @@ set( SIMULATION_HEADER_BASENAMES KSRoot.h ) set( SIMULATION_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Include + ${CMAKE_CURRENT_SOURCE_DIR}/Include ) foreach( BASENAME ${SIMULATION_HEADER_BASENAMES} ) - list( APPEND SIMULATION_HEADER_FILENAMES ${SIMULATION_HEADER_PATH}/${BASENAME} ) + list( APPEND SIMULATION_HEADER_FILENAMES ${SIMULATION_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files @@ -42,10 +42,10 @@ set( SIMULATION_SOURCE_BASENAMES KSTrackMessage.cxx KSStepMessage.cxx KSSimulation.cxx - KSRun.cxx - KSEvent.cxx - KSTrack.cxx - KSStep.cxx + KSRun.cxx + KSEvent.cxx + KSTrack.cxx + KSStep.cxx KSRootElectricField.cxx KSRootMagneticField.cxx KSRootStepModifier.cxx @@ -64,45 +64,40 @@ set( SIMULATION_SOURCE_BASENAMES KSRoot.cxx ) set( SIMULATION_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source + ${CMAKE_CURRENT_SOURCE_DIR}/Source ) foreach( BASENAME ${SIMULATION_SOURCE_BASENAMES} ) - list( APPEND SIMULATION_SOURCE_FILENAMES ${SIMULATION_SOURCE_PATH}/${BASENAME} ) + list( APPEND SIMULATION_SOURCE_FILENAMES ${SIMULATION_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) # data files set( SIMULATION_DATA_BASENAMES ) set( SIMULATION_DATA_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/DataFiles + ${CMAKE_CURRENT_SOURCE_DIR}/DataFiles ) foreach( BASENAME ${SIMULATION_DATA_BASENAMES} ) - list( APPEND SIMULATION_DATA_FILENAMES ${SIMULATION_DATA_PATH}/${BASENAME} ) + list( APPEND SIMULATION_DATA_FILENAMES ${SIMULATION_DATA_PATH}/${BASENAME} ) endforeach( BASENAME ) # library -kasper_internal_include_directories( ${SIMULATION_HEADER_PATH} ) -add_library( KassiopeiaSimulation SHARED ${SIMULATION_SOURCE_FILENAMES} ${SIMULATION_HEADER_FILENAMES} ) -set_target_properties( KassiopeiaSimulation PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) +add_library( KassiopeiaSimulation SHARED + ${SIMULATION_SOURCE_FILENAMES} ${SIMULATION_HEADER_FILENAMES} ) +target_include_directories(KassiopeiaSimulation + PUBLIC $ $ ) target_link_libraries( KassiopeiaSimulation - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - KassiopeiaUtility - KassiopeiaObjects - KassiopeiaOperators - KassiopeiaFields - KassiopeiaGeometry - KassiopeiaGenerators - KassiopeiaTrajectories - KassiopeiaInteractions - KassiopeiaNavigators - KassiopeiaTerminators - KassiopeiaWriters - KassiopeiaModifiers - #KassiopeiaReaders + PUBLIC + KassiopeiaFields + KassiopeiaGenerators + KassiopeiaInteractions + KassiopeiaModifiers + KassiopeiaNavigators + KassiopeiaTerminators + KassiopeiaTrajectories + KassiopeiaWriters ) # install kasper_install_headers( ${SIMULATION_HEADER_FILENAMES} ) -kasper_install_data( ${SIMULATION_DATA_FILENAMES} ) kasper_install_libraries( KassiopeiaSimulation ) +kasper_install_data( ${SIMULATION_DATA_FILENAMES} ) diff --git a/Kassiopeia/Simulation/Source/KSRootSpaceNavigator.cxx b/Kassiopeia/Simulation/Source/KSRootSpaceNavigator.cxx index 7dcfd9b9a..8143ea277 100644 --- a/Kassiopeia/Simulation/Source/KSRootSpaceNavigator.cxx +++ b/Kassiopeia/Simulation/Source/KSRootSpaceNavigator.cxx @@ -175,6 +175,9 @@ void KSRootSpaceNavigator::CalculateNavigation() fStep->SpaceNavigationStep(), fStep->SpaceNavigationFlag()); + if (! fNavigationParticle->IsValid()) + throw KSNavigatorError() << "invalid particle state after navigation calculation"; + if (fStep->SpaceNavigationFlag() == true) { navmsg_debug("space navigation calculation:" << eom); navmsg_debug(" space navigation may occur" << eom); @@ -225,6 +228,9 @@ void KSRootSpaceNavigator::ExecuteNavigation() ExecuteNavigation(*fNavigationParticle, *fFinalParticle, *fParticleQueue); fFinalParticle->ReleaseLabel(fStep->SpaceNavigationName()); + if (! fFinalParticle->IsValid()) + throw KSNavigatorError() << "invalid particle state after navigation execution"; + fStep->ContinuousTime() = fNavigationParticle->GetTime() - fTerminatorParticle->GetTime(); fStep->ContinuousLength() = fNavigationParticle->GetLength() - fTerminatorParticle->GetLength(); fStep->ContinuousEnergyChange() = diff --git a/Kassiopeia/Terminators/CMakeLists.txt b/Kassiopeia/Terminators/CMakeLists.txt index 83f284131..ff8933ea1 100644 --- a/Kassiopeia/Terminators/CMakeLists.txt +++ b/Kassiopeia/Terminators/CMakeLists.txt @@ -23,11 +23,11 @@ set( TERMINATORS_HEADER_BASENAMES KSTermStepsize.h KSTermMagnetron.h ) -set( TERMINATORS_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Include +set( TERMINATORS_HEADER_PATH + ${CMAKE_CURRENT_SOURCE_DIR}/Include ) foreach( BASENAME ${TERMINATORS_HEADER_BASENAMES} ) - list( APPEND TERMINATORS_HEADER_FILENAMES ${TERMINATORS_HEADER_PATH}/${BASENAME} ) + list( APPEND TERMINATORS_HEADER_FILENAMES ${TERMINATORS_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files @@ -54,36 +54,35 @@ set( TERMINATORS_SOURCE_BASENAMES KSTermStepsize.cxx KSTermMagnetron.cxx ) -set( TERMINATORS_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source +set( TERMINATORS_SOURCE_PATH + ${CMAKE_CURRENT_SOURCE_DIR}/Source ) foreach( BASENAME ${TERMINATORS_SOURCE_BASENAMES} ) - list( APPEND TERMINATORS_SOURCE_FILENAMES ${TERMINATORS_SOURCE_PATH}/${BASENAME} ) + list( APPEND TERMINATORS_SOURCE_FILENAMES ${TERMINATORS_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) # data files set( TERMINATORS_DATA_BASENAMES ) -set( TERMINATORS_DATA_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Data +set( TERMINATORS_DATA_PATH + ${CMAKE_CURRENT_SOURCE_DIR}/Data ) foreach( BASENAME ${TERMINATORS_DATA_BASENAMES} ) - list( APPEND TERMINATORS_DATA_FILENAMES ${TERMINATORS_DATA_PATH}/${BASENAME} ) + list( APPEND TERMINATORS_DATA_FILENAMES ${TERMINATORS_DATA_PATH}/${BASENAME} ) endforeach( BASENAME ) # library -kasper_internal_include_directories( ${TERMINATORS_HEADER_PATH} ) -add_library( KassiopeiaTerminators SHARED ${TERMINATORS_SOURCE_FILENAMES} ${TERMINATORS_HEADER_FILENAMES} ) -set_target_properties( KassiopeiaTerminators PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) +add_library( KassiopeiaTerminators SHARED + ${TERMINATORS_SOURCE_FILENAMES} ${TERMINATORS_HEADER_FILENAMES} ) +target_include_directories(KassiopeiaTerminators + PUBLIC $ $ ) target_link_libraries( KassiopeiaTerminators - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - KassiopeiaUtility - KassiopeiaObjects - KassiopeiaOperators + PUBLIC + KassiopeiaOperators + KassiopeiaGeometry ) # install kasper_install_headers( ${TERMINATORS_HEADER_FILENAMES} ) -kasper_install_data( ${TERMINATORS_DATA_FILENAMES} ) kasper_install_libraries( KassiopeiaTerminators ) +kasper_install_data( ${TERMINATORS_DATA_FILENAMES} ) diff --git a/Kassiopeia/Trajectories/CMakeLists.txt b/Kassiopeia/Trajectories/CMakeLists.txt index a5ba76c9c..cebcaa44b 100644 --- a/Kassiopeia/Trajectories/CMakeLists.txt +++ b/Kassiopeia/Trajectories/CMakeLists.txt @@ -1,6 +1,6 @@ # header files set( TRAJECTORIES_HEADER_BASENAMES - KSTrajectoriesMessage.h + KSTrajectoriesMessage.h KSTrajExactParticle.h KSTrajExactDerivative.h @@ -78,10 +78,10 @@ set( TRAJECTORIES_HEADER_BASENAMES KSTrajTrajectoryLinear.h ) set( TRAJECTORIES_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Include + ${CMAKE_CURRENT_SOURCE_DIR}/Include ) foreach( BASENAME ${TRAJECTORIES_HEADER_BASENAMES} ) - list( APPEND TRAJECTORIES_HEADER_FILENAMES ${TRAJECTORIES_HEADER_PATH}/${BASENAME} ) + list( APPEND TRAJECTORIES_HEADER_FILENAMES ${TRAJECTORIES_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files @@ -157,33 +157,32 @@ set( TRAJECTORIES_SOURCE_BASENAMES KSTrajTrajectoryLinear.cxx ) set( TRAJECTORIES_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source + ${CMAKE_CURRENT_SOURCE_DIR}/Source ) foreach( BASENAME ${TRAJECTORIES_SOURCE_BASENAMES} ) - list( APPEND TRAJECTORIES_SOURCE_FILENAMES ${TRAJECTORIES_SOURCE_PATH}/${BASENAME} ) + list( APPEND TRAJECTORIES_SOURCE_FILENAMES ${TRAJECTORIES_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) # data files set( TRAJECTORIES_DATA_BASENAMES ) set( TRAJECTORIES_DATA_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Data + ${CMAKE_CURRENT_SOURCE_DIR}/Data ) foreach( BASENAME ${TRAJECTORIES_DATA_BASENAMES} ) - list( APPEND TRAJECTORIES_DATA_FILENAMES ${TRAJECTORIES_DATA_PATH}/${BASENAME} ) + list( APPEND TRAJECTORIES_DATA_FILENAMES ${TRAJECTORIES_DATA_PATH}/${BASENAME} ) endforeach( BASENAME ) # library -kasper_internal_include_directories( ${TRAJECTORIES_HEADER_PATH} ) -add_library( KassiopeiaTrajectories SHARED ${TRAJECTORIES_SOURCE_FILENAMES} ${TRAJECTORIES_HEADER_FILENAMES} ) -set_target_properties( KassiopeiaTrajectories PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) +add_library( KassiopeiaTrajectories SHARED + ${TRAJECTORIES_SOURCE_FILENAMES} ${TRAJECTORIES_HEADER_FILENAMES} ) +target_include_directories(KassiopeiaTrajectories + PUBLIC $ $ ) target_link_libraries( KassiopeiaTrajectories - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - KassiopeiaUtility - KassiopeiaObjects - KassiopeiaOperators - KassiopeiaMath + PUBLIC + KassiopeiaOperators + KassiopeiaMath + KGeoBagMathSpaceTree ) # install diff --git a/Kassiopeia/Trajectories/Include/KSTrajTermPropagation.h b/Kassiopeia/Trajectories/Include/KSTrajTermPropagation.h index dde117c9a..4d3b4e228 100644 --- a/Kassiopeia/Trajectories/Include/KSTrajTermPropagation.h +++ b/Kassiopeia/Trajectories/Include/KSTrajTermPropagation.h @@ -53,6 +53,7 @@ class KSTrajTermPropagation : } Direction; void SetDirection(const Direction& anDirection); + void ReverseDirection() { fDirection = (fDirection == Direction::eBackward ? Direction::eForward : Direction::eBackward); } private: Direction fDirection; diff --git a/Kassiopeia/Trajectories/Include/KSTrajTrajectoryMagnetic.h b/Kassiopeia/Trajectories/Include/KSTrajTrajectoryMagnetic.h index 4770d8ca6..fc35dc3e9 100644 --- a/Kassiopeia/Trajectories/Include/KSTrajTrajectoryMagnetic.h +++ b/Kassiopeia/Trajectories/Include/KSTrajTrajectoryMagnetic.h @@ -34,8 +34,8 @@ class KSTrajTrajectoryMagnetic : void AddControl(KSTrajMagneticControl* aControl); void RemoveControl(KSTrajMagneticControl* aControl); - void SetReverseDirection(const bool& aFlag); - const bool& GetReverseDirection() const; + //void SetReverseDirection(const bool& aFlag); + //const bool& GetReverseDirection() const; void SetAttemptLimit(unsigned int n) { diff --git a/Kassiopeia/Utility/CMakeLists.txt b/Kassiopeia/Utility/CMakeLists.txt index 2929b0951..dbbb7fb5b 100644 --- a/Kassiopeia/Utility/CMakeLists.txt +++ b/Kassiopeia/Utility/CMakeLists.txt @@ -10,11 +10,11 @@ set( UTILITY_HEADER_BASENAMES KSUtilityMessage.h KSPathResolver.h ) -set( UTILITY_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Include +set( UTILITY_HEADER_PATH + ${CMAKE_CURRENT_SOURCE_DIR}/Include ) foreach( BASENAME ${UTILITY_HEADER_BASENAMES} ) - list( APPEND UTILITY_HEADER_FILENAMES ${UTILITY_HEADER_PATH}/${BASENAME} ) + list( APPEND UTILITY_HEADER_FILENAMES ${UTILITY_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files @@ -23,28 +23,45 @@ set( UTILITY_SOURCE_BASENAMES KSCondition.cxx KSUtilityMessage.cxx ) -set( UTILITY_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source +set( UTILITY_SOURCE_PATH + ${CMAKE_CURRENT_SOURCE_DIR}/Source ) foreach( BASENAME ${UTILITY_SOURCE_BASENAMES} ) - list( APPEND UTILITY_SOURCE_FILENAMES ${UTILITY_SOURCE_PATH}/${BASENAME} ) + list( APPEND UTILITY_SOURCE_FILENAMES ${UTILITY_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) - -# internal -kasper_internal_include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Include -) -# target -kasper_internal_include_directories( ${UTILITY_HEADER_PATH} ) -add_library( KassiopeiaUtility SHARED ${UTILITY_SOURCE_FILENAMES} ${UTILITY_HEADER_FILENAMES} ) +# pthread +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads REQUIRED) + +# library +add_library( KassiopeiaUtility SHARED + ${UTILITY_SOURCE_FILENAMES} ${UTILITY_HEADER_FILENAMES} ) +target_include_directories(KassiopeiaUtility + PUBLIC $ $ ) target_link_libraries( KassiopeiaUtility - pthread - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} + PUBLIC + Kommon + PRIVATE + Threads::Threads ) +if( Kassiopeia_ENABLE_DEBUG ) + target_compile_definitions( KassiopeiaUtility PUBLIC Kassiopeia_ENABLE_DEBUG ) +endif( Kassiopeia_ENABLE_DEBUG ) + +if( Kassiopeia_USE_BOOST ) + target_compile_definitions( KassiopeiaUtility PUBLIC Kassiopeia_USE_BOOST ) +endif( Kassiopeia_USE_BOOST ) + +if( Kassiopeia_USE_ROOT ) + target_compile_definitions( KassiopeiaUtility PUBLIC Kassiopeia_USE_ROOT ) +endif( Kassiopeia_USE_ROOT ) + +if( Kassiopeia_USE_VTK ) + target_compile_definitions( KassiopeiaUtility PUBLIC Kassiopeia_USE_VTK ) +endif( Kassiopeia_USE_VTK ) + # install kasper_install_headers( ${UTILITY_HEADER_FILENAMES} ) kasper_install_libraries( KassiopeiaUtility ) - diff --git a/Kassiopeia/Utility/Source/KSUtilityMessage.cxx b/Kassiopeia/Utility/Source/KSUtilityMessage.cxx index 4a20b578f..2dbed0f61 100644 --- a/Kassiopeia/Utility/Source/KSUtilityMessage.cxx +++ b/Kassiopeia/Utility/Source/KSUtilityMessage.cxx @@ -1,3 +1,3 @@ #include "KSUtilityMessage.h" -KMESSAGE_DEFINE(Kassiopeia, ksutilmsg, KSUtility, KSUTILITY) +KMESSAGE_DEFINE(Kassiopeia, ksutilmsg, ks_utility, KSUTILITY) diff --git a/Kassiopeia/Visualization/CMakeLists.txt b/Kassiopeia/Visualization/CMakeLists.txt index cd266e709..6650d21b3 100644 --- a/Kassiopeia/Visualization/CMakeLists.txt +++ b/Kassiopeia/Visualization/CMakeLists.txt @@ -3,28 +3,26 @@ set( VISUALIZATION_HEADER_BASENAMES KSVisualizationMessage.h ) if( Kassiopeia_USE_ROOT ) - set( VISUALIZATION_HEADER_BASENAMES - ${VISUALIZATION_HEADER_BASENAMES} - KSROOTTrackPainter.h - KSROOTPotentialPainter.h + list(APPEND VISUALIZATION_HEADER_BASENAMES + KSROOTTrackPainter.h + KSROOTPotentialPainter.h KSROOTMagFieldPainter.h KSROOTZonalHarmonicsPainter.h ) - if( Kassiopeia_USE_VTK ) - set( VISUALIZATION_HEADER_BASENAMES - ${VISUALIZATION_HEADER_BASENAMES} - KSVTKGeneratorPainter.h - KSVTKTrackPainter.h - KSVTKTrackTerminatorPainter.h - ) - endif( Kassiopeia_USE_VTK ) + if( Kassiopeia_USE_VTK ) + list(APPEND VISUALIZATION_HEADER_BASENAMES + KSVTKGeneratorPainter.h + KSVTKTrackPainter.h + KSVTKTrackTerminatorPainter.h + ) + endif( Kassiopeia_USE_VTK ) endif( Kassiopeia_USE_ROOT ) set( VISUALIZATION_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Include + ${CMAKE_CURRENT_SOURCE_DIR}/Include ) foreach( BASENAME ${VISUALIZATION_HEADER_BASENAMES} ) - list( APPEND VISUALIZATION_HEADER_FILENAMES ${VISUALIZATION_HEADER_PATH}/${BASENAME} ) + list( APPEND VISUALIZATION_HEADER_FILENAMES ${VISUALIZATION_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files @@ -33,63 +31,58 @@ set( VISUALIZATION_SOURCE_BASENAMES ) if( Kassiopeia_USE_ROOT ) - set( VISUALIZATION_SOURCE_BASENAMES - ${VISUALIZATION_SOURCE_BASENAMES} - KSROOTTrackPainter.cxx - KSROOTPotentialPainter.cxx + list(APPEND VISUALIZATION_SOURCE_BASENAMES + KSROOTTrackPainter.cxx + KSROOTPotentialPainter.cxx KSROOTMagFieldPainter.cxx KSROOTZonalHarmonicsPainter.cxx ) - if( Kassiopeia_USE_VTK ) - set( VISUALIZATION_SOURCE_BASENAMES - ${VISUALIZATION_SOURCE_BASENAMES} - KSVTKGeneratorPainter.cxx - KSVTKTrackPainter.cxx - KSVTKTrackTerminatorPainter.cxx - ) - endif( Kassiopeia_USE_VTK ) + if( Kassiopeia_USE_VTK ) + list(APPEND VISUALIZATION_SOURCE_BASENAMES + KSVTKGeneratorPainter.cxx + KSVTKTrackPainter.cxx + KSVTKTrackTerminatorPainter.cxx + ) + endif( Kassiopeia_USE_VTK ) endif( Kassiopeia_USE_ROOT ) set( VISUALIZATION_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source + ${CMAKE_CURRENT_SOURCE_DIR}/Source ) foreach( BASENAME ${VISUALIZATION_SOURCE_BASENAMES} ) - list( APPEND VISUALIZATION_SOURCE_FILENAMES ${VISUALIZATION_SOURCE_PATH}/${BASENAME} ) + list( APPEND VISUALIZATION_SOURCE_FILENAMES ${VISUALIZATION_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) -if( Kassiopeia_USE_VTK ) - if( VTK_MAJOR_VERSION GREATER 5 ) - set_property( SOURCE ${VISUALIZATION_SOURCE_FILENAMES} ${VISUALIZATION_HEADER_FILENAMES} APPEND PROPERTY - COMPILE_DEFINITIONS VTK6 ) - endif() -endif( Kassiopeia_USE_VTK ) - # data files set( VISUALIZATION_DATA_BASENAMES ) set( VISUALIZATION_DATA_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Data + ${CMAKE_CURRENT_SOURCE_DIR}/Data ) foreach( BASENAME ${VISUALIZATION_DATA_BASENAMES} ) - list( APPEND VISUALIZATION_DATA_FILENAMES ${VISUALIZATION_DATA_PATH}/${BASENAME} ) + list( APPEND VISUALIZATION_DATA_FILENAMES ${VISUALIZATION_DATA_PATH}/${BASENAME} ) endforeach( BASENAME ) # library -kasper_internal_include_directories( ${VISUALIZATION_HEADER_PATH} ) -add_library( KassiopeiaVisualization SHARED ${VISUALIZATION_SOURCE_FILENAMES} ${VISUALIZATION_HEADER_FILENAMES} ) -set_target_properties( KassiopeiaVisualization PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) +add_library( KassiopeiaVisualization SHARED + ${VISUALIZATION_SOURCE_FILENAMES} ${VISUALIZATION_HEADER_FILENAMES} ) +target_include_directories(KassiopeiaVisualization + PUBLIC $ $ ) target_link_libraries( KassiopeiaVisualization - ${Kommon_LIBRARIES} - ${Kommon_Vtk_LIBRARIES} - ${KGeoBag_LIBRARIES} - KassiopeiaFields - KassiopeiaUtility - KassiopeiaObjects - KassiopeiaOperators - KassiopeiaReaders + PUBLIC + KassiopeiaFields + KassiopeiaReaders + KassiopeiaSimulation + KGeoBagInterface ) +if( Kassiopeia_USE_VTK ) + if( VTK_MAJOR_VERSION GREATER 5 ) + target_compile_definitions( KassiopeiaVisualization PRIVATE VTK6 ) + endif() +endif( Kassiopeia_USE_VTK ) + # install kasper_install_headers( ${VISUALIZATION_HEADER_FILENAMES} ) -kasper_install_data( ${VISUALIZATION_DATA_FILENAMES} ) kasper_install_libraries( KassiopeiaVisualization ) +kasper_install_data( ${VISUALIZATION_DATA_FILENAMES} ) diff --git a/Kassiopeia/Visualization/Include/KSROOTZonalHarmonicsPainter.h b/Kassiopeia/Visualization/Include/KSROOTZonalHarmonicsPainter.h index 88f997cf5..e9950577f 100644 --- a/Kassiopeia/Visualization/Include/KSROOTZonalHarmonicsPainter.h +++ b/Kassiopeia/Visualization/Include/KSROOTZonalHarmonicsPainter.h @@ -29,38 +29,23 @@ class KSROOTZonalHarmonicsPainter : public katrin::KROOTPainter std::string GetYAxisLabel() override; private: - ; K_SET(std::string, XAxis); - ; K_SET(std::string, YAxis); - ; K_SET(double, Zmin); - ; K_SET(double, Zmax); - ; K_SET(double, Rmin); - ; K_SET(double, Rmax); - ; K_SET(double, Zdist); - ; K_SET(double, Rdist); - ; K_SET(unsigned, ZMaxSteps); - ; K_SET(unsigned, RMaxSteps); - ; K_SET(std::string, ElectricFieldName); - ; K_SET(std::string, MagneticFieldName); - ; K_SET(std::string, File); - ; K_SET(std::string, Path); - ; K_SET(bool, DrawSourcePoints); - ; - K_SET(bool, DrawSourcePointArea); + K_SET(bool, DrawExpansionArea); + K_SET(bool, DrawConvergenceArea); //;K_SET( std::string, GeometryType ); //;K_SET( double, RadialSafetyMargin ); diff --git a/Kassiopeia/Visualization/Source/KSROOTZonalHarmonicsPainter.cxx b/Kassiopeia/Visualization/Source/KSROOTZonalHarmonicsPainter.cxx index 5134982cd..f2b773027 100644 --- a/Kassiopeia/Visualization/Source/KSROOTZonalHarmonicsPainter.cxx +++ b/Kassiopeia/Visualization/Source/KSROOTZonalHarmonicsPainter.cxx @@ -4,7 +4,9 @@ #include "KGElectrostaticBoundaryField.hh" #include "KGStaticElectromagnetField.hh" #include "KSObject.h" -#include "KSReadFileROOT.h" +#include "KSFieldFinder.h" +#include "KSElectricKEMField.h" +#include "KSMagneticKEMField.h" #include "KSVisualizationMessage.h" #include "KToolbox.h" #include "KZonalHarmonicMagnetostaticFieldSolver.hh" @@ -19,25 +21,6 @@ using namespace KGeoBag; using namespace katrin; using namespace std; -namespace -{ - -void MirrorGraph(TGraph* g) -{ - // used to shade area between graphs, see: https://root.cern.ch/root/html/tutorials/graphics/graphShade.C.html - if (g->GetN() <= 0) - return; - - int n = g->GetN(); - double* x = g->GetX(); - double* y = g->GetY(); - for (int i = 0; i < n; i++) { - g->SetPoint(2 * n - i, x[i], -y[i]); - } -} - -} // namespace - namespace Kassiopeia { KSROOTZonalHarmonicsPainter::KSROOTZonalHarmonicsPainter() : @@ -49,17 +32,15 @@ KSROOTZonalHarmonicsPainter::KSROOTZonalHarmonicsPainter() : fRmax(5.0), fZdist(0.01), fRdist(0.001), - fZMaxSteps(5000), - fRMaxSteps(5000), + fZMaxSteps(1000), + fRMaxSteps(1000), fElectricFieldName(""), fMagneticFieldName(""), fFile(""), fPath(""), fDrawSourcePoints(true), - fDrawSourcePointArea(true) -//fGeometryType ( "surface" ), -//fRadialSafetyMargin( 0. ), -//fZRPoints () + fDrawExpansionArea(false), + fDrawConvergenceArea(true) {} KSROOTZonalHarmonicsPainter::~KSROOTZonalHarmonicsPainter() = default; @@ -71,14 +52,6 @@ void KSROOTZonalHarmonicsPainter::Render() fZmax = std::numeric_limits::min(); } - fElZHConvergenceGraph = new TGraph(); - fElZHCentralGraph = new TGraph(); - fElZHRemoteGraph = new TGraph(); - - fMagZHConvergenceGraph = new TGraph(); - fMagZHCentralGraph = new TGraph(); - fMagZHRemoteGraph = new TGraph(); - fElZHPoints = new TPolyMarker(); fMagZHPoints = new TPolyMarker(); @@ -87,7 +60,14 @@ void KSROOTZonalHarmonicsPainter::Render() KElectricZHFieldSolver* tElZHSolver = nullptr; if (!fElectricFieldName.empty()) { vismsg(eNormal) << "Getting electric field " << fElectricFieldName << " from the toolbox" << eom; + auto* tElField = katrin::KToolbox::GetInstance().Get(fElectricFieldName); + if (! tElField) { + KSElectricField* tFieldWrapper = getElectricField(fElectricFieldName); + auto* tKEMFieldObject = dynamic_cast(tFieldWrapper); + tElField = dynamic_cast(tKEMFieldObject->GetElectricField()); + } + if (tElField == nullptr) vismsg(eError) << "No electric Field!" << eom; vismsg(eNormal) << "Initialize electric field (again)" << eom; @@ -120,7 +100,14 @@ void KSROOTZonalHarmonicsPainter::Render() KZonalHarmonicMagnetostaticFieldSolver* tMagZHSolver = nullptr; if (!fMagneticFieldName.empty()) { vismsg(eNormal) << "Getting magnetic field " << fMagneticFieldName << " from the toolbox" << eom; + auto* tMagField = katrin::KToolbox::GetInstance().Get(fMagneticFieldName); + if (! tMagField) { + KSMagneticField* tFieldWrapper = getMagneticField(fMagneticFieldName); + auto* tKEMFieldObject = dynamic_cast(tFieldWrapper); + tMagField = dynamic_cast(tKEMFieldObject->GetMagneticField()); + } + if (tMagField == nullptr) vismsg(eError) << "No magnetic Field!" << eom; vismsg(eNormal) << "Initialize magnetic field (again)" << eom; @@ -161,13 +148,25 @@ void KSROOTZonalHarmonicsPainter::Render() KThreeVector tPosition; - vismsg(eNormal) << "ZH painter: start calculating convergence boundary from " << fZmin << " to " << fZmax << " m" - << eom; - for (double tZ = fZmin; tZ <= fZmax; tZ += fZdist) { - //vismsg( eInfo ) << "ZH painter: Z Position: " << tZ << eom; - double tR = 0; + unsigned tNPoints = floor((fZmax - fZmin) / fZdist); + + fElZHConvergenceGraph = new TGraph(2*tNPoints); + fElZHCentralGraph = new TGraph(2*tNPoints); + fElZHRemoteGraph = new TGraph(2*tNPoints); + + fMagZHConvergenceGraph = new TGraph(2*tNPoints); + fMagZHCentralGraph = new TGraph(2*tNPoints); + fMagZHRemoteGraph = new TGraph(2*tNPoints); + + vismsg(eNormal) << "ZH painter: start calculating convergence boundary from " << fZmin << " to " << fZmax << " m (" + << tNPoints << " steps) ..." << eom; + + for (unsigned tPointIndex = 0; tPointIndex < tNPoints; tPointIndex++) { + unsigned tNegPointIndex = 2*tNPoints - tPointIndex - 1; + double tZ = fZmin + tPointIndex * fZdist; if (tElZHSolver != nullptr) { + double tR = 0; for (auto& sp : tElZHSolver->CentralSourcePoints()) { double rho = sp.second; double dz = fabs(tZ - sp.first); @@ -179,32 +178,39 @@ void KSROOTZonalHarmonicsPainter::Render() tR = h; } - if (tR >= 0) { - //vismsg(eDebug) << " electric field sourcepoint radius at z=" << tZ << " is r=" << tR << " m" << eom; - fElZHConvergenceGraph->SetPoint(fElZHConvergenceGraph->GetN(), tZ, tR); - } + //vismsg(eDebug) << " electric field sourcepoint radius at z=" << tZ << " is r=" << tR << " m" << eom; + fElZHConvergenceGraph->SetPoint(tPointIndex, tZ, tR); + fElZHConvergenceGraph->SetPoint(tNegPointIndex, tZ, -tR); + + fElZHCentralGraph->SetPoint(tPointIndex, tZ, 0); + fElZHCentralGraph->SetPoint(tNegPointIndex, tZ, 0); + fElZHRemoteGraph->SetPoint(tPointIndex, tZ, 0); + fElZHRemoteGraph->SetPoint(tNegPointIndex, tZ, 0); // scan central convergence region - for (double tRho = 0; tRho <= tR; tRho += fRdist) { + for (double tRho = fRmin; tRho <= tR; tRho += fRdist) { if (!tElZHSolver->UseCentralExpansion(KThreeVector(0, tRho, tZ))) { vismsg(eDebug) << " electric field central convergence limit at z=" << tZ << " is r=" << tRho << " m" << eom; - fElZHCentralGraph->SetPoint(fElZHCentralGraph->GetN(), tZ, tRho - fRdist); break; } + fElZHCentralGraph->SetPoint(tPointIndex, tZ, tRho); + fElZHCentralGraph->SetPoint(tNegPointIndex, tZ, -tRho); } // scan remote convergence region - for (double tRho = tR; tRho >= 0; tRho -= fRdist) { + for (double tRho = fRmax; tRho >= tR; tRho -= fRdist) { if (!tElZHSolver->UseRemoteExpansion(KThreeVector(0, tRho, tZ))) { vismsg(eDebug) << " electric field remote convergence limit at z=" << tZ << " is r=" << tRho << " m" << eom; - fElZHRemoteGraph->SetPoint(fElZHRemoteGraph->GetN(), tZ, tRho + fRdist); break; } + fElZHRemoteGraph->SetPoint(tPointIndex, tZ, tRho); + fElZHRemoteGraph->SetPoint(tNegPointIndex, tZ, -tRho); } } if (tMagZHSolver != nullptr) { + double tR = 0; for (auto& sp : tMagZHSolver->CentralSourcePoints()) { double rho = sp.second; double dz = fabs(tZ - sp.first); @@ -216,66 +222,60 @@ void KSROOTZonalHarmonicsPainter::Render() tR = h; } - if (tR >= 0) { - //vismsg(eDebug) << " magnetic field sourcepoint radius at z=" << tZ << " is r=" << tR << " m" << eom; - fMagZHConvergenceGraph->SetPoint(fMagZHConvergenceGraph->GetN(), tZ, tR); - } + //vismsg(eDebug) << " magnetic field sourcepoint radius at z=" << tZ << " is r=" << tR << " m" << eom; + fMagZHConvergenceGraph->SetPoint(tPointIndex, tZ, tR); + fMagZHConvergenceGraph->SetPoint(tNegPointIndex, tZ, -tR); + + fMagZHCentralGraph->SetPoint(tPointIndex, tZ, 0); + fMagZHCentralGraph->SetPoint(tNegPointIndex, tZ, 0); + fMagZHRemoteGraph->SetPoint(tPointIndex, tZ, 0); + fMagZHRemoteGraph->SetPoint(tNegPointIndex, tZ, 0); // scan central convergence region - for (double tRho = 0; tRho <= tR; tRho += fRdist) { + for (double tRho = fRmin; tRho <= tR; tRho += fRdist) { if (!tMagZHSolver->UseCentralExpansion(KThreeVector(0, tRho, tZ))) { vismsg(eDebug) << " magnetic field central convergence limit at z=" << tZ << " is r=" << tRho << " m" << eom; - fMagZHCentralGraph->SetPoint(fMagZHCentralGraph->GetN(), tZ, tRho - fRdist); break; } + fMagZHCentralGraph->SetPoint(tPointIndex, tZ, tRho); + fMagZHCentralGraph->SetPoint(tNegPointIndex, tZ, -tRho); } // scan central remote region - for (double tRho = tR; tRho >= 0; tRho -= fRdist) { + for (double tRho = fRmax; tRho >= tR; tRho -= fRdist) { if (!tMagZHSolver->UseRemoteExpansion(KThreeVector(0, tRho, tZ))) { vismsg(eDebug) << " magnetic field remote convergence limit at z=" << tZ << " is r=" << tRho << " m" << eom; - fMagZHRemoteGraph->SetPoint(fMagZHRemoteGraph->GetN(), tZ, tRho + fRdist); break; } + fMagZHRemoteGraph->SetPoint(tPointIndex, tZ, tRho); + fMagZHRemoteGraph->SetPoint(tNegPointIndex, tZ, -tRho); } } } if (tElZHSolver != nullptr) { - // add lower part of graphs (negative R) for filled draw, points in reverse order - MirrorGraph(fElZHConvergenceGraph); - MirrorGraph(fElZHCentralGraph); - MirrorGraph(fElZHRemoteGraph); - fElZHConvergenceGraph->SetLineColor(kRed); - fElZHConvergenceGraph->SetLineStyle(kDotted); fElZHCentralGraph->SetLineColor(kRed); - fElZHCentralGraph->SetFillColorAlpha(kRed, 0.1); - + fElZHCentralGraph->SetLineStyle(kDotted); fElZHRemoteGraph->SetLineColor(kRed); + fElZHRemoteGraph->SetLineStyle(kDashed); - fElZHPoints->SetMarkerColor(kRed); - fElZHPoints->SetMarkerStyle(kFullDotMedium); + fElZHPoints->SetMarkerColor(kBlack); + fElZHPoints->SetMarkerStyle(kFullDotSmall); } if (tMagZHSolver != nullptr) { - // add lower part of graph (negative R) for filled draw, points in reverse order - MirrorGraph(fMagZHConvergenceGraph); - MirrorGraph(fMagZHCentralGraph); - MirrorGraph(fMagZHRemoteGraph); - fMagZHConvergenceGraph->SetLineColor(kBlue); - fMagZHConvergenceGraph->SetLineStyle(kDotted); fMagZHCentralGraph->SetLineColor(kBlue); - fMagZHCentralGraph->SetFillColorAlpha(kBlue, 0.1); - + fMagZHCentralGraph->SetLineStyle(kDotted); fMagZHRemoteGraph->SetLineColor(kBlue); + fMagZHRemoteGraph->SetLineStyle(kDashed); - fMagZHPoints->SetMarkerColor(kBlue); - fMagZHPoints->SetMarkerStyle(kFullDotMedium); + fMagZHPoints->SetMarkerColor(kBlack); + fMagZHPoints->SetMarkerStyle(kFullDotSmall); } return; @@ -286,30 +286,31 @@ void KSROOTZonalHarmonicsPainter::Display() if (fDisplayEnabled == true) { // draw order may be important, who knows what ROOT does anyway ... - auto tGraphsFilled = new TMultiGraph(); auto tGraphs = new TMultiGraph(); - if (fElZHCentralGraph->GetN() > 0) - tGraphsFilled->Add(fElZHCentralGraph); - if (fMagZHCentralGraph->GetN() > 0) - tGraphsFilled->Add(fMagZHCentralGraph); - - // FIXME: this is confusing - //if (fElZHRemoteGraph->GetN() > 0) - // tGraphs->Add(fElZHRemoteGraph); - //if (fMagZHRemoteGraph->GetN() > 0) - // tGraphs->Add(fMagZHRemoteGraph); + // TODO: make this an option + if (fDrawExpansionArea) { + if (fElZHCentralGraph->GetN() > 0) + tGraphs->Add(fElZHCentralGraph); + if (fMagZHCentralGraph->GetN() > 0) + tGraphs->Add(fMagZHCentralGraph); + + // FIXME: this is confusing + if (fElZHRemoteGraph->GetN() > 0) + tGraphs->Add(fElZHRemoteGraph); + if (fMagZHRemoteGraph->GetN() > 0) + tGraphs->Add(fMagZHRemoteGraph); + } // TODO: make this an option - if (fDrawSourcePointArea) { + if (fDrawConvergenceArea) { if (fElZHConvergenceGraph->GetN() > 0) tGraphs->Add(fElZHConvergenceGraph); if (fMagZHConvergenceGraph->GetN() > 0) tGraphs->Add(fMagZHConvergenceGraph); } - tGraphsFilled->Draw("fl"); - tGraphs->Draw("l"); + tGraphs->Draw("L"); // TODO: make this an option if (fDrawSourcePoints) { diff --git a/Kassiopeia/Visualization/Source/KSVTKTrackPainter.cxx b/Kassiopeia/Visualization/Source/KSVTKTrackPainter.cxx index deac7353e..19e211e46 100644 --- a/Kassiopeia/Visualization/Source/KSVTKTrackPainter.cxx +++ b/Kassiopeia/Visualization/Source/KSVTKTrackPainter.cxx @@ -64,6 +64,11 @@ void KSVTKTrackPainter::Render() KSReadTrackROOT& tTrack = tReader.GetTrack(); KSReadStepROOT& tStep = tReader.GetStep(); + if (! (tStep.HasObject(fPointObject) && tStep.HasObject(fColorObject))) { + vismsg(eWarning) << "Object <" << fPointObject << "> and <" << fColorObject << "> does not exist in file <" << tRootFile->GetName() << ">" << eom; + return; + } + KSReadObjectROOT& tPointObject = tStep.GetObject(fPointObject); const KSThreeVector& tPointVariable = tPointObject.Get(fPointVariable); diff --git a/Kassiopeia/Visualization/Source/KSVTKTrackTerminatorPainter.cxx b/Kassiopeia/Visualization/Source/KSVTKTrackTerminatorPainter.cxx index 679ce7291..277334108 100644 --- a/Kassiopeia/Visualization/Source/KSVTKTrackTerminatorPainter.cxx +++ b/Kassiopeia/Visualization/Source/KSVTKTrackTerminatorPainter.cxx @@ -61,7 +61,7 @@ void KSVTKTrackTerminatorPainter::Render() const KSThreeVector& tPointVariable = tPointObject.Get(fPointVariable); KSReadObjectROOT& tTerminatorObject = tTrack.GetObject(fTerminatorObject); - const KSString& tTerminatorVariable = tPointObject.Get(fTerminatorVariable); + const KSString& tTerminatorVariable = tTerminatorObject.Get(fTerminatorVariable); // TODO: Use it or delete it. bool tActive; vtkIdType tId; diff --git a/Kassiopeia/Writers/CMakeLists.txt b/Kassiopeia/Writers/CMakeLists.txt index cc23393d3..6a5678309 100644 --- a/Kassiopeia/Writers/CMakeLists.txt +++ b/Kassiopeia/Writers/CMakeLists.txt @@ -5,26 +5,26 @@ set( WRITERS_HEADER_BASENAMES ) if( Kassiopeia_USE_VTK ) set( WRITERS_HEADER_BASENAMES - ${WRITER_HEADER_BASENAMES} - KSWriteVTK.h + ${WRITER_HEADER_BASENAMES} + KSWriteVTK.h ) endif( Kassiopeia_USE_VTK ) if( Kassiopeia_USE_ROOT ) set( WRITERS_HEADER_BASENAMES - ${WRITER_HEADER_BASENAMES} - KSWriteROOT.h - KSWriteROOTCondition.h - KSWriteROOTConditionOutput.h + ${WRITER_HEADER_BASENAMES} + KSWriteROOT.h + KSWriteROOTCondition.h + KSWriteROOTConditionOutput.h KSWriteROOTConditionPeriodic.h KSWriteROOTConditionTerminator.h KSWriteROOTConditionStep.h ) endif( Kassiopeia_USE_ROOT ) set( WRITERS_HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Include + ${CMAKE_CURRENT_SOURCE_DIR}/Include ) foreach( BASENAME ${WRITERS_HEADER_BASENAMES} ) - list( APPEND WRITERS_HEADER_FILENAMES ${WRITERS_HEADER_PATH}/${BASENAME} ) + list( APPEND WRITERS_HEADER_FILENAMES ${WRITERS_HEADER_PATH}/${BASENAME} ) endforeach( BASENAME ) # source files @@ -34,53 +34,53 @@ set( WRITERS_SOURCE_BASENAMES ) if( Kassiopeia_USE_VTK ) set( WRITERS_SOURCE_BASENAMES - ${WRITERS_SOURCE_BASENAMES} - KSWriteVTK.cxx + ${WRITERS_SOURCE_BASENAMES} + KSWriteVTK.cxx ) endif( Kassiopeia_USE_VTK ) if( Kassiopeia_USE_ROOT ) set( WRITERS_SOURCE_BASENAMES - ${WRITERS_SOURCE_BASENAMES} - KSWriteROOT.cxx - KSWriteROOTCondition.cxx + ${WRITERS_SOURCE_BASENAMES} + KSWriteROOT.cxx + KSWriteROOTCondition.cxx ) endif( Kassiopeia_USE_ROOT ) set( WRITERS_SOURCE_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Source + ${CMAKE_CURRENT_SOURCE_DIR}/Source ) foreach( BASENAME ${WRITERS_SOURCE_BASENAMES} ) - list( APPEND WRITERS_SOURCE_FILENAMES ${WRITERS_SOURCE_PATH}/${BASENAME} ) + list( APPEND WRITERS_SOURCE_FILENAMES ${WRITERS_SOURCE_PATH}/${BASENAME} ) endforeach( BASENAME ) -if( Kassiopeia_USE_VTK ) - if( VTK_MAJOR_VERSION GREATER 5 ) - set_property( SOURCE ${WRITERS_SOURCE_FILENAMES} ${WRITERS_HEADER_FILENAMES} APPEND PROPERTY - COMPILE_DEFINITIONS VTK6 ) - endif() -endif( Kassiopeia_USE_VTK ) - # data files set( WRITERS_DATA_BASENAMES ) set( WRITERS_DATA_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/Data + ${CMAKE_CURRENT_SOURCE_DIR}/Data ) foreach( BASENAME ${WRITERS_DATA_BASENAMES} ) - list( APPEND WRITERS_DATA_FILENAMES ${WRITERS_DATA_PATH}/${BASENAME} ) + list( APPEND WRITERS_DATA_FILENAMES ${WRITERS_DATA_PATH}/${BASENAME} ) endforeach( BASENAME ) # library -kasper_internal_include_directories( ${WRITERS_HEADER_PATH} ) -add_library( KassiopeiaWriters SHARED ${WRITERS_SOURCE_FILENAMES} ${WRITERS_HEADER_FILENAMES} ) -set_target_properties( KassiopeiaWriters PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) +add_library( KassiopeiaWriters SHARED + ${WRITERS_SOURCE_FILENAMES} ${WRITERS_HEADER_FILENAMES} ) +target_include_directories(KassiopeiaWriters + PUBLIC $ $ ) target_link_libraries( KassiopeiaWriters - ${Kommon_LIBRARIES} - ${KGeoBag_LIBRARIES} - KassiopeiaUtility - KassiopeiaObjects - KassiopeiaOperators + PUBLIC + KassiopeiaOperators + ROOT::Tree + ROOT::Physics ) +if( Kassiopeia_USE_VTK ) + target_link_libraries( KassiopeiaWriters PUBLIC KommonVtk ) + if( VTK_MAJOR_VERSION GREATER 5 ) + target_compile_definitions( KassiopeiaWriters PRIVATE VTK6 ) + endif() +endif( Kassiopeia_USE_VTK ) + # install kasper_install_headers( ${WRITERS_HEADER_FILENAMES} ) kasper_install_data( ${WRITERS_DATA_FILENAMES} ) diff --git a/Kassiopeia/Writers/Include/KSWriteASCII.h b/Kassiopeia/Writers/Include/KSWriteASCII.h index 97b99f74c..e1f211204 100644 --- a/Kassiopeia/Writers/Include/KSWriteASCII.h +++ b/Kassiopeia/Writers/Include/KSWriteASCII.h @@ -4,8 +4,10 @@ #include "KFile.h" #include "KSWriter.h" #include "KTextFile.h" -#include "KThreeVector.hh" #include "KTwoVector.hh" +#include "KThreeVector.hh" +#include "KTwoMatrix.hh" +#include "KThreeMatrix.hh" #include diff --git a/Kassiopeia/Writers/Include/KSWriteROOT.h b/Kassiopeia/Writers/Include/KSWriteROOT.h index fb8792610..249e7b2e7 100644 --- a/Kassiopeia/Writers/Include/KSWriteROOT.h +++ b/Kassiopeia/Writers/Include/KSWriteROOT.h @@ -6,8 +6,10 @@ #include "KSList.h" #include "KSWriteROOTCondition.h" #include "KSWriter.h" -#include "KThreeVector.hh" #include "KTwoVector.hh" +#include "KThreeVector.hh" +#include "KTwoMatrix.hh" +#include "KThreeMatrix.hh" #include "TFile.h" #include "TString.h" #include "TTree.h" diff --git a/Kassiopeia/Writers/Include/KSWriteVTK.h b/Kassiopeia/Writers/Include/KSWriteVTK.h index e8ee6dbfc..2e8d7a86b 100644 --- a/Kassiopeia/Writers/Include/KSWriteVTK.h +++ b/Kassiopeia/Writers/Include/KSWriteVTK.h @@ -2,20 +2,24 @@ #define _Kassiopeia_KSWriteVTK_h_ #include "KSWriter.h" -#include "KThreeVector.hh" #include "KTwoVector.hh" +#include "KThreeVector.hh" +#include "KTwoMatrix.hh" +#include "KThreeMatrix.hh" #include "vtkCellArray.h" #include "vtkCharArray.h" #include "vtkDoubleArray.h" #include "vtkFloatArray.h" #include "vtkIntArray.h" #include "vtkLongArray.h" +#include "vtkLongLongArray.h" #include "vtkPointData.h" #include "vtkPoints.h" #include "vtkPolyData.h" #include "vtkPolyLine.h" #include "vtkShortArray.h" #include "vtkSmartPointer.h" +#include "vtkStringArray.h" #include "vtkUnsignedCharArray.h" #include "vtkUnsignedIntArray.h" #include "vtkUnsignedLongArray.h" @@ -38,11 +42,12 @@ class KSWriteVTK : public KSComponentTemplate virtual void Execute() = 0; }; - class UIntAction : public Action + template + class SimpleAction : public Action { public: - UIntAction(unsigned int* aData, vtkSmartPointer anArray) : fData(aData), fArray(anArray) {} - ~UIntAction() override = default; + SimpleAction(T* aData, vtkSmartPointer anArray) : fData(aData), fArray(anArray) {} + ~SimpleAction() override = default; void Execute() override { @@ -51,98 +56,103 @@ class KSWriteVTK : public KSComponentTemplate } private: - unsigned int* fData; - vtkSmartPointer fArray; + T* fData; + vtkSmartPointer fArray; }; - class IntAction : public Action - { - public: - IntAction(int* aData, vtkSmartPointer anArray) : fData(aData), fArray(anArray) {} - ~IntAction() override = default; + using StringAction = SimpleAction; + using BoolAction = SimpleAction; + using UCharAction = SimpleAction; + using CharAction = SimpleAction; + using UShortAction = SimpleAction; + using ShortAction = SimpleAction; + using UIntAction = SimpleAction; + using IntAction = SimpleAction; + using ULongAction = SimpleAction; + using LongAction = SimpleAction; + using LongLongAction = SimpleAction; + using FloatAction = SimpleAction; + using DoubleAction = SimpleAction; - void Execute() override - { - fArray->InsertNextValue(*fData); - return; - } - - private: - int* fData; - vtkSmartPointer fArray; - }; - - class FloatAction : public Action + class TwoVectorAction : public Action { public: - FloatAction(float* aData, vtkSmartPointer anArray) : fData(aData), fArray(anArray) {} - ~FloatAction() override = default; + TwoVectorAction(KGeoBag::KTwoVector* aData, vtkSmartPointer anArray) : + fData(aData), + fArray(anArray) + {} + ~TwoVectorAction() override = default; void Execute() override { - fArray->InsertNextValue(*fData); + fArray->InsertNextTuple2(fData->X(), fData->Y()); return; } private: - float* fData; - vtkSmartPointer fArray; + KGeoBag::KTwoVector* fData; + vtkSmartPointer fArray; }; - class DoubleAction : public Action + class ThreeVectorAction : public Action { public: - DoubleAction(double* aData, vtkSmartPointer anArray) : fData(aData), fArray(anArray) {} - ~DoubleAction() override = default; + ThreeVectorAction(KGeoBag::KThreeVector* aData, vtkSmartPointer anArray) : + fData(aData), + fArray(anArray) + {} + ~ThreeVectorAction() override = default; void Execute() override { - fArray->InsertNextValue(*fData); + fArray->InsertNextTuple3(fData->X(), fData->Y(), fData->Z()); return; } private: - double* fData; + KGeoBag::KThreeVector* fData; vtkSmartPointer fArray; }; - class TwoVectorAction : public Action + class TwoMatrixAction : public Action { public: - TwoVectorAction(KGeoBag::KTwoVector* aData, vtkSmartPointer anArray) : + TwoMatrixAction(KGeoBag::KTwoMatrix* aData, vtkSmartPointer anArray) : fData(aData), fArray(anArray) {} - ~TwoVectorAction() override = default; + ~TwoMatrixAction() override = default; void Execute() override { - fArray->InsertNextTuple2(fData->X(), fData->Y()); + fArray->InsertNextTuple4(fData->At(0), fData->At(1), fData->At(2), fData->At(3)); return; } private: - KGeoBag::KTwoVector* fData; + KGeoBag::KTwoMatrix* fData; vtkSmartPointer fArray; }; - class ThreeVectorAction : public Action + class ThreeMatrixAction : public Action { public: - ThreeVectorAction(KGeoBag::KThreeVector* aData, vtkSmartPointer anArray) : + ThreeMatrixAction(KGeoBag::KThreeMatrix* aData, vtkSmartPointer anArray) : fData(aData), fArray(anArray) {} - ~ThreeVectorAction() override = default; + ~ThreeMatrixAction() override = default; void Execute() override { - fArray->InsertNextTuple3(fData->X(), fData->Y(), fData->Z()); + fArray->InsertNextTuple9(fData->At(0), fData->At(1), fData->At(2), + fData->At(3), fData->At(4), fData->At(5), + fData->At(6), fData->At(7), fData->At(8)); return; } private: - KGeoBag::KThreeVector* fData; + KGeoBag::KThreeMatrix* fData; vtkSmartPointer fArray; }; diff --git a/Kassiopeia/Writers/Source/KSWriteASCII.cxx b/Kassiopeia/Writers/Source/KSWriteASCII.cxx index 31f0d32ea..4ef6d0712 100644 --- a/Kassiopeia/Writers/Source/KSWriteASCII.cxx +++ b/Kassiopeia/Writers/Source/KSWriteASCII.cxx @@ -9,7 +9,10 @@ using namespace std; using namespace katrin; -using namespace KGeoBag; +using KGeoBag::KTwoVector; +using KGeoBag::KThreeVector; +using KGeoBag::KTwoMatrix; +using KGeoBag::KThreeMatrix; namespace Kassiopeia { @@ -27,10 +30,9 @@ KSWriteASCII::Data::Objekt::Objekt(KSComponent* aComponent, string aType, int aP string KSWriteASCII::Data::Objekt::getValue() { - stringstream s; s << std::setprecision(fPrecision); - if (fType == "string") + if (fType == (string) "string") s << *(fComponent->As()) << "\t"; else if (fType == (string) "bool") s << *(fComponent->As()) << "\t"; @@ -40,25 +42,35 @@ string KSWriteASCII::Data::Objekt::getValue() s << *(fComponent->As()) << "\t"; else if (fType == (string) "unsigned short") s << *(fComponent->As()) << "\t"; + else if (fType == (string) "short") + s << *(fComponent->As()) << "\t"; else if (fType == (string) "unsigned int") s << *(fComponent->As()) << "\t"; + else if (fType == (string) "int") + s << *(fComponent->As()) << "\t"; else if (fType == (string) "unsigned long") s << *(fComponent->As()) << "\t"; else if (fType == (string) "long") s << *(fComponent->As()) << "\t"; - else if (fType == (string) "int") - s << *(fComponent->As()) << "\t"; - else if (fType == (string) "short") - s << *(fComponent->As()) << "\t"; + else if (fType == (string) "long long") + s << *(fComponent->As()) << "\t"; else if (fType == (string) "float") s << *(fComponent->As()) << "\t"; else if (fType == (string) "double") s << *(fComponent->As()) << "\t"; else if (fType == (string) "KThreeVector") - s << fComponent->As()->X() << "\t" << fComponent->As()->Y() << "\t" + s << fComponent->As()->X() << "\t" + << fComponent->As()->Y() << "\t" << fComponent->As()->Z() << "\t"; else if (fType == (string) "KTwoVector") - s << fComponent->As()->X() << "\t" << fComponent->As()->Y() << "\t"; + s << fComponent->As()->X() << "\t" + << fComponent->As()->Y() << "\t"; + else if (fType == (string) "KTwoMatrix") + for (unsigned i = 0; i < 4; i++) + s << *(fComponent->As())[i] << "\t"; + else if (fType == (string) "KThreeMatrix") + for (unsigned i = 0; i < 9; i++) + s << *(fComponent->As())[i] << "\t"; else s << "\t" << "\t"; @@ -111,11 +123,12 @@ void KSWriteASCII::Data::Fill() string str; for (auto& objekt : fObjekts) { tObjekt = objekt; - str = string(tObjekt->getValue().c_str()); + str = tObjekt->getValue(); for (char& it : str) fWriter->TextFile()->File()->put(it); } + for (tIt = fComponents.begin(); tIt != fComponents.end(); ++tIt) { tComponent = (*tIt); tComponent->PullDeupdate(); @@ -127,29 +140,28 @@ void KSWriteASCII::Data::Fill() void KSWriteASCII::Data::MakeTitle(KSComponent* aComponent, int aTrack) { - wtrmsg_debug("making title for object <" << aComponent->GetName() << ">" << eom) + wtrmsg_debug("making title for object <" << aComponent->GetName() << ">" << eom); - auto* tComponentGroup = aComponent->As(); + auto* tComponentGroup = aComponent->As(); if (tComponentGroup != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a group" - << eom) for (unsigned int tIndex = 0; tIndex < tComponentGroup->ComponentCount(); - tIndex++) MakeTitle(tComponentGroup->ComponentAt(tIndex), aTrack); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a group" << eom); + for (unsigned int tIndex = 0; tIndex < tComponentGroup->ComponentCount(); tIndex++) + MakeTitle(tComponentGroup->ComponentAt(tIndex), aTrack); return; } auto* tString = aComponent->As(); if (tString != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a string" << eom) auto* str = - new string((aComponent->GetName() + '\t').c_str()); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a string" << eom); + string str = (aComponent->GetName() + '\t'); - for (char& it : *str) + for (char& it : str) fWriter->TextFile()->File()->put(it); if (aTrack == 0) { auto* obj = new Objekt(aComponent, "string", fWriter->Precision()); fObjekts.push_back(obj); - fComponents.push_back(aComponent); } @@ -158,10 +170,10 @@ void KSWriteASCII::Data::MakeTitle(KSComponent* aComponent, int aTrack) auto* tTwoVector = aComponent->As(); if (tTwoVector != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a two_vector" << eom) auto* str = new string( - (aComponent->GetName() + string("_x") + '\t' + aComponent->GetName() + string("_y") + '\t').c_str()); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a two_vector" << eom); + string str = (aComponent->GetName() + string("_x") + '\t' + aComponent->GetName() + string("_y") + '\t'); - for (char& it : *str) + for (char& it : str) fWriter->TextFile()->File()->put(it); if (aTrack == 0) { @@ -171,21 +183,52 @@ void KSWriteASCII::Data::MakeTitle(KSComponent* aComponent, int aTrack) } return; } - auto* tThreeVector = aComponent->As(); if (tThreeVector != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a three_vector" << eom) auto* str = - new string((aComponent->GetName() + string("_x") + '\t' + aComponent->GetName() + string("_y") + '\t' + - aComponent->GetName() + string("_z") + '\t') - .c_str()); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a three_vector" << eom); + string str = (aComponent->GetName() + string("_x") + '\t' + aComponent->GetName() + string("_y") + '\t' + + aComponent->GetName() + string("_z") + '\t'); - for (char& it : *str) + for (char& it : str) fWriter->TextFile()->File()->put(it); if (aTrack == 0) { auto* obj = new Objekt(aComponent, "KThreeVector", fWriter->Precision()); fObjekts.push_back(obj); + fComponents.push_back(aComponent); + } + return; + } + + auto* tTwoMatrix = aComponent->As(); + if (tTwoMatrix != nullptr) { + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a two_matrix" << eom); + string str = (aComponent->GetName() + string("_xx") + '\t' + aComponent->GetName() + string("_xy") + + aComponent->GetName() + string("_yx") + '\t' + aComponent->GetName() + string("_yy")); + + for (char& it : str) + fWriter->TextFile()->File()->put(it); + + if (aTrack == 0) { + auto* obj = new Objekt(aComponent, "KTwoMatrix", fWriter->Precision()); + fObjekts.push_back(obj); + fComponents.push_back(aComponent); + } + return; + } + auto* tThreeMatrix = aComponent->As(); + if (tThreeMatrix != nullptr) { + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a three_matrix" << eom); + string str = (aComponent->GetName() + string("_xx") + '\t' + aComponent->GetName() + string("_xy") + '\t' + aComponent->GetName() + string("_xz") + '\t' + + aComponent->GetName() + string("_yx") + '\t' + aComponent->GetName() + string("_yy") + '\t' + aComponent->GetName() + string("_yz") + '\t' + + aComponent->GetName() + string("_zx") + '\t' + aComponent->GetName() + string("_zy") + '\t' + aComponent->GetName() + string("_zz") + '\t'); + for (char& it : str) + fWriter->TextFile()->File()->put(it); + + if (aTrack == 0) { + auto* obj = new Objekt(aComponent, "KThreeMatrix", fWriter->Precision()); + fObjekts.push_back(obj); fComponents.push_back(aComponent); } return; @@ -193,16 +236,15 @@ void KSWriteASCII::Data::MakeTitle(KSComponent* aComponent, int aTrack) auto* tBool = aComponent->As(); if (tBool != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a bool" << eom) auto* str = - new string((aComponent->GetName() + '\t').c_str()); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a bool" << eom); + string str = (aComponent->GetName() + '\t'); - for (char& it : *str) + for (char& it : str) fWriter->TextFile()->File()->put(it); if (aTrack == 0) { auto* obj = new Objekt(aComponent, "bool", fWriter->Precision()); fObjekts.push_back(obj); - fComponents.push_back(aComponent); } return; @@ -210,16 +252,15 @@ void KSWriteASCII::Data::MakeTitle(KSComponent* aComponent, int aTrack) auto* tUChar = aComponent->As(); if (tUChar != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is an unsigned_char" << eom) auto* str = - new string((aComponent->GetName() + '\t').c_str()); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is an unsigned_char" << eom); + string str = (aComponent->GetName() + '\t'); - for (char& it : *str) + for (char& it : str) fWriter->TextFile()->File()->put(it); if (aTrack == 0) { auto* obj = new Objekt(aComponent, "unsigned char", fWriter->Precision()); fObjekts.push_back(obj); - fComponents.push_back(aComponent); } return; @@ -227,16 +268,15 @@ void KSWriteASCII::Data::MakeTitle(KSComponent* aComponent, int aTrack) auto* tChar = aComponent->As(); if (tChar != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a char" << eom) auto* str = - new string((aComponent->GetName() + '\t').c_str()); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a char" << eom); + string str = (aComponent->GetName() + '\t'); - for (char& it : *str) + for (char& it : str) fWriter->TextFile()->File()->put(it); if (aTrack == 0) { auto* obj = new Objekt(aComponent, "char", fWriter->Precision()); fObjekts.push_back(obj); - fComponents.push_back(aComponent); } return; @@ -244,16 +284,15 @@ void KSWriteASCII::Data::MakeTitle(KSComponent* aComponent, int aTrack) auto* tUShort = aComponent->As(); if (tUShort != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is an unsigned_short" << eom) auto* str = - new string((aComponent->GetName() + '\t').c_str()); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is an unsigned_short" << eom); + string str = (aComponent->GetName() + '\t'); - for (char& it : *str) + for (char& it : str) fWriter->TextFile()->File()->put(it); if (aTrack == 0) { auto* obj = new Objekt(aComponent, "unsigned short", fWriter->Precision()); fObjekts.push_back(obj); - fComponents.push_back(aComponent); } return; @@ -261,16 +300,15 @@ void KSWriteASCII::Data::MakeTitle(KSComponent* aComponent, int aTrack) auto* tShort = aComponent->As(); if (tShort != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a short" << eom) auto* str = - new string((aComponent->GetName() + '\t').c_str()); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a short" << eom); + string str = (aComponent->GetName() + '\t'); - for (char& it : *str) + for (char& it : str) fWriter->TextFile()->File()->put(it); if (aTrack == 0) { auto* obj = new Objekt(aComponent, "short", fWriter->Precision()); fObjekts.push_back(obj); - fComponents.push_back(aComponent); } return; @@ -278,16 +316,15 @@ void KSWriteASCII::Data::MakeTitle(KSComponent* aComponent, int aTrack) auto* tUInt = aComponent->As(); if (tUInt != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a unsigned_int" << eom) auto* str = - new string((aComponent->GetName() + '\t').c_str()); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a unsigned_int" << eom); + string str = (aComponent->GetName() + '\t'); - for (char& it : *str) + for (char& it : str) fWriter->TextFile()->File()->put(it); if (aTrack == 0) { auto* obj = new Objekt(aComponent, "unsigned int", fWriter->Precision()); fObjekts.push_back(obj); - fComponents.push_back(aComponent); } return; @@ -295,16 +332,15 @@ void KSWriteASCII::Data::MakeTitle(KSComponent* aComponent, int aTrack) auto* tInt = aComponent->As(); if (tInt != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is an int" << eom) auto* str = - new string((aComponent->GetName() + '\t').c_str()); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is an int" << eom); + string str = (aComponent->GetName() + '\t'); - for (char& it : *str) + for (char& it : str) fWriter->TextFile()->File()->put(it); if (aTrack == 0) { auto* obj = new Objekt(aComponent, "int", fWriter->Precision()); fObjekts.push_back(obj); - fComponents.push_back(aComponent); } return; @@ -312,16 +348,15 @@ void KSWriteASCII::Data::MakeTitle(KSComponent* aComponent, int aTrack) auto* tULong = aComponent->As(); if (tULong != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is an unsigned_long" << eom) auto* str = - new string((aComponent->GetName() + '\t').c_str()); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is an unsigned_long" << eom); + string str = (aComponent->GetName() + '\t'); - for (char& it : *str) + for (char& it : str) fWriter->TextFile()->File()->put(it); if (aTrack == 0) { auto* obj = new Objekt(aComponent, "unsigned long", fWriter->Precision()); fObjekts.push_back(obj); - fComponents.push_back(aComponent); } return; @@ -329,16 +364,31 @@ void KSWriteASCII::Data::MakeTitle(KSComponent* aComponent, int aTrack) auto* tLong = aComponent->As(); if (tLong != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a long" << eom) auto* str = - new string((aComponent->GetName() + '\t').c_str()); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a long" << eom); + string str = (aComponent->GetName() + '\t'); - for (char& it : *str) + for (char& it : str) fWriter->TextFile()->File()->put(it); if (aTrack == 0) { auto* obj = new Objekt(aComponent, "long", fWriter->Precision()); fObjekts.push_back(obj); + fComponents.push_back(aComponent); + } + return; + } + + auto* tLongLong = aComponent->As(); + if (tLongLong != nullptr) { + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a long_long" << eom); + string str = (aComponent->GetName() + '\t'); + + for (char& it : str) + fWriter->TextFile()->File()->put(it); + if (aTrack == 0) { + auto* obj = new Objekt(aComponent, "long_long", fWriter->Precision()); + fObjekts.push_back(obj); fComponents.push_back(aComponent); } return; @@ -346,16 +396,15 @@ void KSWriteASCII::Data::MakeTitle(KSComponent* aComponent, int aTrack) auto* tFloat = aComponent->As(); if (tFloat != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a float" << eom) auto* str = - new string((aComponent->GetName() + '\t').c_str()); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a float" << eom); + string str = (aComponent->GetName() + '\t'); - for (char& it : *str) + for (char& it : str) fWriter->TextFile()->File()->put(it); if (aTrack == 0) { auto* obj = new Objekt(aComponent, "float", fWriter->Precision()); fObjekts.push_back(obj); - fComponents.push_back(aComponent); } return; @@ -363,16 +412,15 @@ void KSWriteASCII::Data::MakeTitle(KSComponent* aComponent, int aTrack) auto* tDouble = aComponent->As(); if (tDouble != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a double" << eom) auto* str = - new string((aComponent->GetName() + '\t').c_str()); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a double" << eom); + string str = (aComponent->GetName() + '\t'); - for (char& it : *str) + for (char& it : str) fWriter->TextFile()->File()->put(it); if (aTrack == 0) { auto* obj = new Objekt(aComponent, "double", fWriter->Precision()); fObjekts.push_back(obj); - fComponents.push_back(aComponent); } return; @@ -511,15 +559,17 @@ void KSWriteASCII::ExecuteTrack() if (fStepIndex != 0) fTrackLastStepIndex = fStepIndex - 1; - ComponentIt tIt; - fTextFile->File()->put('\n'); for (auto& activeTrackComponent : fActiveTrackComponents) activeTrackComponent.second->Fill(); + wtrmsg(eNormal) << "ASCII output was written to file <" << fTextFile->GetName() << ">" << eom; fTextFile->Close(); + delete fTextFile; + // new output file + fTextFile = MakeOutputFile(fTrackIndex + 1); if (fTextFile->Open(KFile::eWrite) == true) { // do nothing here @@ -528,6 +578,8 @@ void KSWriteASCII::ExecuteTrack() wtrmsg(eError) << "could not open ASCII output file" << eom; } + ComponentIt tIt; + for (tIt = fTrackComponents.begin(); tIt != fTrackComponents.end(); tIt++) tIt->second->MakeTitle(tIt->first, 0); @@ -548,6 +600,7 @@ void KSWriteASCII::ExecuteStep() fStepIterationIndex++; return; } + fTextFile->File()->put('\n'); if (fStepComponent == true) { wtrmsg_debug("ASCII writer <" << GetName() << "> is filling a step" << eom); @@ -639,7 +692,6 @@ void KSWriteASCII::AddTrackComponent(KSComponent* aComponent) auto* tTrackData = new Data(aComponent, this); tIt = fTrackComponents.insert(ComponentEntry(aComponent, tTrackData)).first; - fTextFile->File()->put('\n'); } wtrmsg_debug("ASCII writer is starting a track output called <" << aComponent->GetName() << ">" << eom); @@ -703,14 +755,6 @@ void KSWriteASCII::InitializeComponent() { wtrmsg_debug("starting ASCII writer" << eom); - stringstream s; - s << fBase << "_Track" << fTrackIndex << +".txt"; - string tBase = s.str(); - string tPath = fPath.empty() ? OUTPUT_DEFAULT_DIR : fPath; - -#ifdef Kassiopeia_USE_BOOST - KPathUtils::MakeDirectory(tPath); -#endif fTextFile = MakeOutputFile(fTrackIndex); if (fTextFile->Open(KFile::eWrite) == true) { @@ -734,10 +778,10 @@ void KSWriteASCII::DeinitializeComponent() for (tIt = fStepComponents.begin(); tIt != fStepComponents.end(); tIt++) delete tIt->second; - wtrmsg(eNormal) << "ASCII output was written to file <" << fTextFile->GetName() << ">" << eom; fTextFile->Close(); delete fTextFile; + return; } diff --git a/Kassiopeia/Writers/Source/KSWriteROOT.cxx b/Kassiopeia/Writers/Source/KSWriteROOT.cxx index 8a06e8166..dc6117a99 100644 --- a/Kassiopeia/Writers/Source/KSWriteROOT.cxx +++ b/Kassiopeia/Writers/Source/KSWriteROOT.cxx @@ -11,7 +11,10 @@ using katrin::KPathUtils; #include "TObjString.h" using namespace std; -using namespace KGeoBag; +using KGeoBag::KTwoVector; +using KGeoBag::KThreeVector; +using KGeoBag::KTwoMatrix; +using KGeoBag::KThreeMatrix; namespace Kassiopeia { @@ -100,7 +103,8 @@ void KSWriteROOT::Data::MakeBranches(KSComponent* aComponent) auto* tComponentGroup = aComponent->As(); if (tComponentGroup != nullptr) { wtrmsg_debug(" object <" << aComponent->GetName() << "> is a group" - << eom) for (unsigned int tIndex = 0; tIndex < tComponentGroup->ComponentCount(); + << eom); + for (unsigned int tIndex = 0; tIndex < tComponentGroup->ComponentCount(); tIndex++) { MakeBranches(tComponentGroup->ComponentAt(tIndex)); @@ -110,7 +114,8 @@ void KSWriteROOT::Data::MakeBranches(KSComponent* aComponent) auto* tString = aComponent->As(); if (tString != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a string" << eom) fLabel = aComponent->GetName(); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a string" << eom); + fLabel = aComponent->GetName(); fType = string("string"); fStructure->Fill(); fData->Branch(aComponent->GetName().c_str(), tString, fBufferSize, fSplitLevel); @@ -120,8 +125,8 @@ void KSWriteROOT::Data::MakeBranches(KSComponent* aComponent) auto* tTwoVector = aComponent->As(); if (tTwoVector != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a two_vector" << eom) fLabel = - aComponent->GetName(); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a two_vector" << eom); + fLabel = aComponent->GetName(); fType = string("two_vector"); fStructure->Fill(); fData->Branch((aComponent->GetName() + string("_x")).c_str(), &(tTwoVector->X()), fBufferSize, fSplitLevel); @@ -131,8 +136,8 @@ void KSWriteROOT::Data::MakeBranches(KSComponent* aComponent) } auto* tThreeVector = aComponent->As(); if (tThreeVector != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a three_vector" << eom) fLabel = - aComponent->GetName(); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a three_vector" << eom); + fLabel = aComponent->GetName(); fType = string("three_vector"); fStructure->Fill(); fData->Branch((aComponent->GetName() + string("_x")).c_str(), &(tThreeVector->X()), fBufferSize, fSplitLevel); @@ -142,9 +147,42 @@ void KSWriteROOT::Data::MakeBranches(KSComponent* aComponent) return; } + auto* tTwoMatrix = aComponent->As(); + if (tTwoMatrix != nullptr) { + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a two_matrix" << eom); + fLabel = aComponent->GetName(); + fType = string("two_matrix"); + fStructure->Fill(); + fData->Branch((aComponent->GetName() + string("_xx")).c_str(), &(tTwoMatrix->At(0,0)), fBufferSize, fSplitLevel); + fData->Branch((aComponent->GetName() + string("_xy")).c_str(), &(tTwoMatrix->At(0,1)), fBufferSize, fSplitLevel); + fData->Branch((aComponent->GetName() + string("_yx")).c_str(), &(tTwoMatrix->At(1,0)), fBufferSize, fSplitLevel); + fData->Branch((aComponent->GetName() + string("_yy")).c_str(), &(tTwoMatrix->At(1,1)), fBufferSize, fSplitLevel); + fComponents.push_back(aComponent); + return; + } + auto* tThreeMatrix = aComponent->As(); + if (tThreeMatrix != nullptr) { + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a three_matrix" << eom); + fLabel = aComponent->GetName(); + fType = string("three_matrix"); + fStructure->Fill(); + fData->Branch((aComponent->GetName() + string("_xx")).c_str(), &(tThreeMatrix->At(0,0)), fBufferSize, fSplitLevel); + fData->Branch((aComponent->GetName() + string("_xy")).c_str(), &(tThreeMatrix->At(0,1)), fBufferSize, fSplitLevel); + fData->Branch((aComponent->GetName() + string("_xz")).c_str(), &(tThreeMatrix->At(0,2)), fBufferSize, fSplitLevel); + fData->Branch((aComponent->GetName() + string("_yx")).c_str(), &(tThreeMatrix->At(1,0)), fBufferSize, fSplitLevel); + fData->Branch((aComponent->GetName() + string("_yy")).c_str(), &(tThreeMatrix->At(1,1)), fBufferSize, fSplitLevel); + fData->Branch((aComponent->GetName() + string("_yz")).c_str(), &(tThreeMatrix->At(1,2)), fBufferSize, fSplitLevel); + fData->Branch((aComponent->GetName() + string("_zx")).c_str(), &(tThreeMatrix->At(2,0)), fBufferSize, fSplitLevel); + fData->Branch((aComponent->GetName() + string("_zy")).c_str(), &(tThreeMatrix->At(2,1)), fBufferSize, fSplitLevel); + fData->Branch((aComponent->GetName() + string("_zz")).c_str(), &(tThreeMatrix->At(2,2)), fBufferSize, fSplitLevel); + fComponents.push_back(aComponent); + return; + } + auto* tBool = aComponent->As(); if (tBool != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a bool" << eom) fLabel = aComponent->GetName(); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a bool" << eom); + fLabel = aComponent->GetName(); fType = string("bool"); fStructure->Fill(); fData->Branch(aComponent->GetName().c_str(), tBool, fBufferSize, fSplitLevel); @@ -154,8 +192,8 @@ void KSWriteROOT::Data::MakeBranches(KSComponent* aComponent) auto* tUChar = aComponent->As(); if (tUChar != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is an unsigned_char" << eom) fLabel = - aComponent->GetName(); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is an unsigned_char" << eom); + fLabel = aComponent->GetName(); fType = string("unsigned_char"); fStructure->Fill(); fData->Branch(aComponent->GetName().c_str(), tUChar, fBufferSize, fSplitLevel); @@ -164,7 +202,8 @@ void KSWriteROOT::Data::MakeBranches(KSComponent* aComponent) } auto* tChar = aComponent->As(); if (tChar != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a char" << eom) fLabel = aComponent->GetName(); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a char" << eom); + fLabel = aComponent->GetName(); fType = string("char"); fStructure->Fill(); fData->Branch(aComponent->GetName().c_str(), tChar, fBufferSize, fSplitLevel); @@ -174,8 +213,8 @@ void KSWriteROOT::Data::MakeBranches(KSComponent* aComponent) auto* tUShort = aComponent->As(); if (tUShort != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is an unsigned_short" << eom) fLabel = - aComponent->GetName(); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is an unsigned_short" << eom); + fLabel = aComponent->GetName(); fType = string("unsigned_short"); fStructure->Fill(); fData->Branch(aComponent->GetName().c_str(), tUShort, fBufferSize, fSplitLevel); @@ -184,7 +223,8 @@ void KSWriteROOT::Data::MakeBranches(KSComponent* aComponent) } auto* tShort = aComponent->As(); if (tShort != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a short" << eom) fLabel = aComponent->GetName(); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a short" << eom); + fLabel = aComponent->GetName(); fType = string("short"); fStructure->Fill(); fData->Branch(aComponent->GetName().c_str(), tShort, fBufferSize, fSplitLevel); @@ -194,8 +234,8 @@ void KSWriteROOT::Data::MakeBranches(KSComponent* aComponent) auto* tUInt = aComponent->As(); if (tUInt != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a unsigned_int" << eom) fLabel = - aComponent->GetName(); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a unsigned_int" << eom); + fLabel = aComponent->GetName(); fType = string("unsigned_int"); fStructure->Fill(); fData->Branch(aComponent->GetName().c_str(), tUInt, fBufferSize, fSplitLevel); @@ -204,7 +244,8 @@ void KSWriteROOT::Data::MakeBranches(KSComponent* aComponent) } auto* tInt = aComponent->As(); if (tInt != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is an int" << eom) fLabel = aComponent->GetName(); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is an int" << eom); + fLabel = aComponent->GetName(); fType = string("int"); fStructure->Fill(); fData->Branch(aComponent->GetName().c_str(), tInt, fBufferSize, fSplitLevel); @@ -214,8 +255,8 @@ void KSWriteROOT::Data::MakeBranches(KSComponent* aComponent) auto* tULong = aComponent->As(); if (tULong != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is an unsigned_long" << eom) fLabel = - aComponent->GetName(); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is an unsigned_long" << eom); + fLabel = aComponent->GetName(); fType = string("unsigned_long"); fStructure->Fill(); fData->Branch(aComponent->GetName().c_str(), tULong, fBufferSize, fSplitLevel); @@ -224,7 +265,8 @@ void KSWriteROOT::Data::MakeBranches(KSComponent* aComponent) } auto* tLong = aComponent->As(); if (tLong != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a long" << eom) fLabel = aComponent->GetName(); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a long" << eom); + fLabel = aComponent->GetName(); fType = string("long"); fStructure->Fill(); fData->Branch(aComponent->GetName().c_str(), tLong, fBufferSize, fSplitLevel); @@ -233,8 +275,9 @@ void KSWriteROOT::Data::MakeBranches(KSComponent* aComponent) } auto* tLongLong = aComponent->As(); if (tLongLong != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a long long" << eom) fLabel = aComponent->GetName(); - fType = string("long long"); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a long_long" << eom); + fLabel = aComponent->GetName(); + fType = string("long_long"); fStructure->Fill(); fData->Branch(aComponent->GetName().c_str(), tLongLong, fBufferSize, fSplitLevel); fComponents.push_back(aComponent); @@ -243,7 +286,8 @@ void KSWriteROOT::Data::MakeBranches(KSComponent* aComponent) auto* tFloat = aComponent->As(); if (tFloat != nullptr) { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a float" << eom) fLabel = aComponent->GetName(); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a float" << eom); + fLabel = aComponent->GetName(); fType = string("float"); fStructure->Fill(); fData->Branch(aComponent->GetName().c_str(), tFloat, fBufferSize, fSplitLevel); @@ -252,7 +296,8 @@ void KSWriteROOT::Data::MakeBranches(KSComponent* aComponent) } auto* tDouble = aComponent->As(); { - wtrmsg_debug(" object <" << aComponent->GetName() << "> is a double" << eom) fLabel = aComponent->GetName(); + wtrmsg_debug(" object <" << aComponent->GetName() << "> is a double" << eom); + fLabel = aComponent->GetName(); fType = string("double"); fStructure->Fill(); fData->Branch(aComponent->GetName().c_str(), tDouble, fBufferSize, fSplitLevel); diff --git a/Kassiopeia/Writers/Source/KSWriteVTK.cxx b/Kassiopeia/Writers/Source/KSWriteVTK.cxx index 7f53326a4..8271d90f0 100644 --- a/Kassiopeia/Writers/Source/KSWriteVTK.cxx +++ b/Kassiopeia/Writers/Source/KSWriteVTK.cxx @@ -10,8 +10,10 @@ using katrin::KPathUtils; #endif using namespace std; -using KGeoBag::KThreeVector; using KGeoBag::KTwoVector; +using KGeoBag::KThreeVector; +using KGeoBag::KTwoMatrix; +using KGeoBag::KThreeMatrix; namespace Kassiopeia { @@ -376,12 +378,12 @@ void KSWriteVTK::DeinitializeComponent() void KSWriteVTK::AddTrackPoint(KSComponent* anComponent) { wtrmsg_debug("VTK writer <" << GetName() << "> making track point action for object <" << anComponent->GetName() - << ">" << eom) + << ">" << eom); auto* tThreeVector = anComponent->As(); if (tThreeVector != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a three_vector" << eom) fTrackPointAction.first = - anComponent; + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a three_vector" << eom); + fTrackPointAction.first = anComponent; fTrackPointAction.second = new PointAction(tThreeVector, fTrackIds, fTrackPoints); return; } @@ -395,14 +397,12 @@ void KSWriteVTK::AddTrackPoint(KSComponent* anComponent) void KSWriteVTK::AddTrackData(KSComponent* anComponent) { wtrmsg_debug("VTK writer <" << GetName() << "> making track data action for object <" << anComponent->GetName() - << ">" << eom) + << ">" << eom); auto* tComponentGroup = anComponent->As(); if (tComponentGroup != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a group" - << eom) for (unsigned int tIndex = 0; tIndex < tComponentGroup->ComponentCount(); - tIndex++) - { + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a group" << eom); + for (unsigned int tIndex = 0; tIndex < tComponentGroup->ComponentCount(); tIndex++) { AddTrackData(tComponentGroup->ComponentAt(tIndex)); } return; @@ -410,16 +410,19 @@ void KSWriteVTK::AddTrackData(KSComponent* anComponent) auto* tString = anComponent->As(); if (tString != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a string" << eom) wtrmsg(eWarning) - << " ignoring string object <" << anComponent->GetName() << ">" << eom; + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a string" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(1); + fTrackData->GetPointData()->AddArray(tArray); + fTrackDataActions.insert(ActionEntry(anComponent, new StringAction(tString, tArray))); return; } auto* tTwoVector = anComponent->As(); if (tTwoVector != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a two_vector" << eom) - vtkSmartPointer - tArray = vtkSmartPointer::New(); + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a two_vector" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); tArray->SetName(anComponent->GetName().c_str()); tArray->SetNumberOfComponents(2); fTrackData->GetPointData()->AddArray(tArray); @@ -428,9 +431,8 @@ void KSWriteVTK::AddTrackData(KSComponent* anComponent) } auto* tThreeVector = anComponent->As(); if (tThreeVector != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a three_vector" << eom) - vtkSmartPointer - tArray = vtkSmartPointer::New(); + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a three_vector" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); tArray->SetName(anComponent->GetName().c_str()); tArray->SetNumberOfComponents(3); fTrackData->GetPointData()->AddArray(tArray); @@ -438,29 +440,83 @@ void KSWriteVTK::AddTrackData(KSComponent* anComponent) return; } + auto* tTwoMatrix = anComponent->As(); + if (tTwoMatrix != nullptr) { + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a two_matrix" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(4); + fTrackData->GetPointData()->AddArray(tArray); + fTrackDataActions.insert(ActionEntry(anComponent, new TwoMatrixAction(tTwoMatrix, tArray))); + return; + } + auto* tThreeMatrix = anComponent->As(); + if (tThreeMatrix != nullptr) { + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a three_matrix" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(9); + fTrackData->GetPointData()->AddArray(tArray); + fTrackDataActions.insert(ActionEntry(anComponent, new ThreeMatrixAction(tThreeMatrix, tArray))); + return; + } + bool* tBool = anComponent->As(); if (tBool != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a bool" << eom) wtrmsg(eWarning) - << " ignoring bool object <" << anComponent->GetName() << ">" << eom; + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a bool" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(1); + fTrackData->GetPointData()->AddArray(tArray); + fTrackDataActions.insert(ActionEntry(anComponent, new BoolAction(tBool, tArray))); + return; + } + + auto* tUChar = anComponent->As(); + if (tUChar != nullptr) { + wtrmsg_debug(" object <" << anComponent->GetName() << "> is an unsigned_short" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(1); + fTrackData->GetPointData()->AddArray(tArray); + fTrackDataActions.insert(ActionEntry(anComponent, new UCharAction(tUChar, tArray))); + return; + } + auto* tChar = anComponent->As(); + if (tChar != nullptr) { + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a short" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(1); + fTrackData->GetPointData()->AddArray(tArray); + fTrackDataActions.insert(ActionEntry(anComponent, new CharAction(tChar, tArray))); return; } auto* tUShort = anComponent->As(); if (tUShort != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is an unsigned_short" << eom) wtrmsg(eWarning) - << " ignoring unsigned short object <" << anComponent->GetName() << ">" << eom; + wtrmsg_debug(" object <" << anComponent->GetName() << "> is an unsigned_short" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(1); + fTrackData->GetPointData()->AddArray(tArray); + fTrackDataActions.insert(ActionEntry(anComponent, new UShortAction(tUShort, tArray))); return; } auto* tShort = anComponent->As(); if (tShort != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a short" << eom) wtrmsg(eWarning) - << " ignoring short object <" << anComponent->GetName() << ">" << eom; + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a short" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(1); + fTrackData->GetPointData()->AddArray(tArray); + fTrackDataActions.insert(ActionEntry(anComponent, new ShortAction(tShort, tArray))); return; } auto* tUInt = anComponent->As(); if (tUInt != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a unsigned_int" << eom) + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a unsigned_int" << eom); vtkSmartPointer tArray = vtkSmartPointer::New(); tArray->SetName(anComponent->GetName().c_str()); @@ -471,7 +527,7 @@ void KSWriteVTK::AddTrackData(KSComponent* anComponent) } int* tInt = anComponent->As(); if (tInt != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is an int" << eom) vtkSmartPointer + wtrmsg_debug(" object <" << anComponent->GetName() << "> is an int" << eom); vtkSmartPointer tArray = vtkSmartPointer::New(); tArray->SetName(anComponent->GetName().c_str()); tArray->SetNumberOfComponents(1); @@ -482,21 +538,39 @@ void KSWriteVTK::AddTrackData(KSComponent* anComponent) auto* tULong = anComponent->As(); if (tULong != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is an unsigned_long" << eom) wtrmsg(eWarning) - << " ignoring unsigned long object <" << anComponent->GetName() << ">" << eom; + wtrmsg_debug(" object <" << anComponent->GetName() << "> is an unsigned_long" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(1); + fTrackData->GetPointData()->AddArray(tArray); + fTrackDataActions.insert(ActionEntry(anComponent, new ULongAction(tULong, tArray))); return; } long* tLong = anComponent->As(); if (tLong != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a long" << eom) wtrmsg(eWarning) - << " ignoring long object <" << anComponent->GetName() << ">" << eom; + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a long" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(1); + fTrackData->GetPointData()->AddArray(tArray); + fTrackDataActions.insert(ActionEntry(anComponent, new LongAction(tLong, tArray))); + return; + } + long long* tLongLong = anComponent->As(); + if (tLongLong != nullptr) { + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a long_long" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(1); + fTrackData->GetPointData()->AddArray(tArray); + fTrackDataActions.insert(ActionEntry(anComponent, new LongLongAction(tLongLong, tArray))); return; } auto* tFloat = anComponent->As(); if (tFloat != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a float" << eom) vtkSmartPointer - tArray = vtkSmartPointer::New(); + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a float" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); tArray->SetName(anComponent->GetName().c_str()); tArray->SetNumberOfComponents(1); fTrackData->GetPointData()->AddArray(tArray); @@ -505,8 +579,8 @@ void KSWriteVTK::AddTrackData(KSComponent* anComponent) } auto* tDouble = anComponent->As(); if (tDouble != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a double" << eom) vtkSmartPointer - tArray = vtkSmartPointer::New(); + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a double" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); tArray->SetName(anComponent->GetName().c_str()); tArray->SetNumberOfComponents(1); fTrackData->GetPointData()->AddArray(tArray); @@ -564,12 +638,12 @@ void KSWriteVTK::BreakTrack() void KSWriteVTK::AddStepPoint(KSComponent* anComponent) { wtrmsg_debug("VTK writer <" << GetName() << "> making step point action for object <" << anComponent->GetName() - << ">" << eom) + << ">" << eom); auto* tThreeVector = anComponent->As(); if (tThreeVector != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a three_vector" << eom) fStepPointAction.first = - anComponent; + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a three_vector" << eom); + fStepPointAction.first = anComponent; fStepPointAction.second = new PointAction(tThreeVector, fStepIds, fStepPoints); return; } @@ -583,14 +657,12 @@ void KSWriteVTK::AddStepPoint(KSComponent* anComponent) void KSWriteVTK::AddStepData(KSComponent* anComponent) { wtrmsg_debug("VTK writer <" << GetName() << "> making step data action for object <" << anComponent->GetName() - << ">" << eom) + << ">" << eom); auto* tComponentGroup = anComponent->As(); if (tComponentGroup != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a group" - << eom) for (unsigned int tIndex = 0; tIndex < tComponentGroup->ComponentCount(); - tIndex++) - { + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a group" << eom); + for (unsigned int tIndex = 0; tIndex < tComponentGroup->ComponentCount(); tIndex++) { AddStepData(tComponentGroup->ComponentAt(tIndex)); } return; @@ -598,16 +670,19 @@ void KSWriteVTK::AddStepData(KSComponent* anComponent) auto* tString = anComponent->As(); if (tString != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a string" << eom) wtrmsg(eWarning) - << " ignoring string object <" << anComponent->GetName() << ">" << eom; + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a string" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(1); + fStepData->GetPointData()->AddArray(tArray); + fStepDataActions.insert(ActionEntry(anComponent, new StringAction(tString, tArray))); return; } auto* tTwoVector = anComponent->As(); if (tTwoVector != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a two_vector" << eom) - vtkSmartPointer - tArray = vtkSmartPointer::New(); + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a two_vector" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); tArray->SetName(anComponent->GetName().c_str()); tArray->SetNumberOfComponents(2); fStepData->GetPointData()->AddArray(tArray); @@ -616,9 +691,8 @@ void KSWriteVTK::AddStepData(KSComponent* anComponent) } auto* tThreeVector = anComponent->As(); if (tThreeVector != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a three_vector" << eom) - vtkSmartPointer - tArray = vtkSmartPointer::New(); + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a three_vector" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); tArray->SetName(anComponent->GetName().c_str()); tArray->SetNumberOfComponents(3); fStepData->GetPointData()->AddArray(tArray); @@ -626,31 +700,85 @@ void KSWriteVTK::AddStepData(KSComponent* anComponent) return; } + auto* tTwoMatrix = anComponent->As(); + if (tTwoMatrix != nullptr) { + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a two_matrix" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(4); + fStepData->GetPointData()->AddArray(tArray); + fStepDataActions.insert(ActionEntry(anComponent, new TwoMatrixAction(tTwoMatrix, tArray))); + return; + } + auto* tThreeMatrix = anComponent->As(); + if (tThreeMatrix != nullptr) { + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a three_matrix" << eom); + vtkSmartPointer + tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(9); + fStepData->GetPointData()->AddArray(tArray); + fStepDataActions.insert(ActionEntry(anComponent, new ThreeMatrixAction(tThreeMatrix, tArray))); + return; + } + bool* tBool = anComponent->As(); if (tBool != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a bool" << eom) wtrmsg(eWarning) - << " ignoring bool object <" << anComponent->GetName() << ">" << eom; + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a bool" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(1); + fStepData->GetPointData()->AddArray(tArray); + fStepDataActions.insert(ActionEntry(anComponent, new BoolAction(tBool, tArray))); + return; + } + + auto* tUChar = anComponent->As(); + if (tUChar != nullptr) { + wtrmsg_debug(" object <" << anComponent->GetName() << "> is an unsigned_short" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(1); + fStepData->GetPointData()->AddArray(tArray); + fStepDataActions.insert(ActionEntry(anComponent, new UCharAction(tUChar, tArray))); + return; + } + auto* tChar = anComponent->As(); + if (tChar != nullptr) { + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a short" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(1); + fStepData->GetPointData()->AddArray(tArray); + fStepDataActions.insert(ActionEntry(anComponent, new CharAction(tChar, tArray))); return; } auto* tUShort = anComponent->As(); if (tUShort != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is an unsigned_short" << eom) wtrmsg(eWarning) - << " ignoring unsigned short object <" << anComponent->GetName() << ">" << eom; + wtrmsg_debug(" object <" << anComponent->GetName() << "> is an unsigned_short" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(1); + fStepData->GetPointData()->AddArray(tArray); + fStepDataActions.insert(ActionEntry(anComponent, new UShortAction(tUShort, tArray))); return; } auto* tShort = anComponent->As(); if (tShort != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a short" << eom) wtrmsg(eWarning) - << " ignoring short object <" << anComponent->GetName() << ">" << eom; + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a short" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(1); + fStepData->GetPointData()->AddArray(tArray); + fStepDataActions.insert(ActionEntry(anComponent, new ShortAction(tShort, tArray))); return; } auto* tUInt = anComponent->As(); if (tUInt != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a unsigned_int" << eom) - vtkSmartPointer - tArray = vtkSmartPointer::New(); + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a unsigned_int" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); tArray->SetName(anComponent->GetName().c_str()); tArray->SetNumberOfComponents(1); fStepData->GetPointData()->AddArray(tArray); @@ -659,8 +787,8 @@ void KSWriteVTK::AddStepData(KSComponent* anComponent) } int* tInt = anComponent->As(); if (tInt != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is an int" << eom) vtkSmartPointer - tArray = vtkSmartPointer::New(); + wtrmsg_debug(" object <" << anComponent->GetName() << "> is an int" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); tArray->SetName(anComponent->GetName().c_str()); tArray->SetNumberOfComponents(1); fStepData->GetPointData()->AddArray(tArray); @@ -670,21 +798,39 @@ void KSWriteVTK::AddStepData(KSComponent* anComponent) auto* tULong = anComponent->As(); if (tULong != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is an unsigned_long" << eom) wtrmsg(eWarning) - << " ignoring unsigned long object <" << anComponent->GetName() << ">" << eom; + wtrmsg_debug(" object <" << anComponent->GetName() << "> is an unsigned_long" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(1); + fStepData->GetPointData()->AddArray(tArray); + fStepDataActions.insert(ActionEntry(anComponent, new ULongAction(tULong, tArray))); return; } long* tLong = anComponent->As(); if (tLong != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a long" << eom) wtrmsg(eWarning) - << " ignoring long object <" << anComponent->GetName() << ">" << eom; + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a long" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(1); + fStepData->GetPointData()->AddArray(tArray); + fStepDataActions.insert(ActionEntry(anComponent, new LongAction(tLong, tArray))); + return; + } + long long* tLongLong = anComponent->As(); + if (tLongLong != nullptr) { + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a long_long" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); + tArray->SetName(anComponent->GetName().c_str()); + tArray->SetNumberOfComponents(1); + fStepData->GetPointData()->AddArray(tArray); + fStepDataActions.insert(ActionEntry(anComponent, new LongLongAction(tLongLong, tArray))); return; } auto* tFloat = anComponent->As(); if (tFloat != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a float" << eom) vtkSmartPointer - tArray = vtkSmartPointer::New(); + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a float" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); tArray->SetName(anComponent->GetName().c_str()); tArray->SetNumberOfComponents(1); fStepData->GetPointData()->AddArray(tArray); @@ -693,8 +839,8 @@ void KSWriteVTK::AddStepData(KSComponent* anComponent) } auto* tDouble = anComponent->As(); if (tDouble != nullptr) { - wtrmsg_debug(" object <" << anComponent->GetName() << "> is a double" << eom) vtkSmartPointer - tArray = vtkSmartPointer::New(); + wtrmsg_debug(" object <" << anComponent->GetName() << "> is a double" << eom); + vtkSmartPointer tArray = vtkSmartPointer::New(); tArray->SetName(anComponent->GetName().c_str()); tArray->SetNumberOfComponents(1); fStepData->GetPointData()->AddArray(tArray); diff --git a/Kassiopeia/XML/CMakeLists.txt b/Kassiopeia/XML/CMakeLists.txt index 68eba68c3..4028aed14 100644 --- a/Kassiopeia/XML/CMakeLists.txt +++ b/Kassiopeia/XML/CMakeLists.txt @@ -20,7 +20,7 @@ kasper_install_config_subdir( Validation Validation/TestDiscreteRotationalField.xml Validation/TestNavigation.xml Validation/TestPotentialmap.xml - Validation/TestSynchrotron.xml + Validation/TestSynchrotron.xml ) if( Kassiopeia_USE_VTK ) @@ -31,6 +31,7 @@ if( Kassiopeia_USE_VTK ) Examples/VTK/DipoleTrapMeshedSpaceSimulation.xml Examples/VTK/ToricTrapSimulation.xml Examples/VTK/PhotoMultiplierTubeSimulation.xml + Examples/VTK/MeshSimulation.xml ) else( Kassiopeia_USE_VTK ) kasper_install_config_subdir( Examples @@ -40,6 +41,7 @@ else( Kassiopeia_USE_VTK ) Examples/DipoleTrapMeshedSpaceSimulation.xml Examples/ToricTrapSimulation.xml Examples/PhotoMultiplierTubeSimulation.xml + Examples/MeshSimulation.xml ) endif( Kassiopeia_USE_VTK ) diff --git a/Kassiopeia/XML/Examples/AnalyticSimulation.xml b/Kassiopeia/XML/Examples/AnalyticSimulation.xml index cf53a5860..2532c41bd 100644 --- a/Kassiopeia/XML/Examples/AnalyticSimulation.xml +++ b/Kassiopeia/XML/Examples/AnalyticSimulation.xml @@ -13,7 +13,7 @@ - + @@ -63,18 +63,18 @@ - + - - + + + + @@ -124,7 +128,7 @@ - + @@ -134,11 +138,11 @@ - + - + @@ -201,7 +205,7 @@ - + diff --git a/Kassiopeia/XML/Examples/DipoleTrapMeshedSpaceSimulation.xml b/Kassiopeia/XML/Examples/DipoleTrapMeshedSpaceSimulation.xml index 386b99875..ffc70c3d3 100644 --- a/Kassiopeia/XML/Examples/DipoleTrapMeshedSpaceSimulation.xml +++ b/Kassiopeia/XML/Examples/DipoleTrapMeshedSpaceSimulation.xml @@ -186,11 +186,11 @@ - + - - + - - + - + + + + diff --git a/Kassiopeia/XML/Examples/DipoleTrapSimulation.xml b/Kassiopeia/XML/Examples/DipoleTrapSimulation.xml index 1153e8729..c92f991ee 100644 --- a/Kassiopeia/XML/Examples/DipoleTrapSimulation.xml +++ b/Kassiopeia/XML/Examples/DipoleTrapSimulation.xml @@ -141,11 +141,11 @@ - + - - + - - + - + + + + diff --git a/Kassiopeia/XML/Examples/MeshSimulation.xml b/Kassiopeia/XML/Examples/MeshSimulation.xml new file mode 100644 index 000000000..1a7d98ec8 --- /dev/null +++ b/Kassiopeia/XML/Examples/MeshSimulation.xml @@ -0,0 +1,342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Kassiopeia/XML/Examples/PhotoMultiplierTubeSimulation.xml b/Kassiopeia/XML/Examples/PhotoMultiplierTubeSimulation.xml index bb1efe21f..698d7be7b 100644 --- a/Kassiopeia/XML/Examples/PhotoMultiplierTubeSimulation.xml +++ b/Kassiopeia/XML/Examples/PhotoMultiplierTubeSimulation.xml @@ -18,7 +18,7 @@ - + @@ -325,12 +325,11 @@ - - + - - + + + + diff --git a/Kassiopeia/XML/Examples/QuadrupoleTrapSimulation.xml b/Kassiopeia/XML/Examples/QuadrupoleTrapSimulation.xml index 0f121285a..1d9ddbe78 100644 --- a/Kassiopeia/XML/Examples/QuadrupoleTrapSimulation.xml +++ b/Kassiopeia/XML/Examples/QuadrupoleTrapSimulation.xml @@ -139,11 +139,11 @@ - + - - + - - + + + + + @@ -272,7 +276,7 @@ - + diff --git a/Kassiopeia/XML/Examples/ToricTrapSimulation.xml b/Kassiopeia/XML/Examples/ToricTrapSimulation.xml index 8b5a45a31..ef7f55b27 100644 --- a/Kassiopeia/XML/Examples/ToricTrapSimulation.xml +++ b/Kassiopeia/XML/Examples/ToricTrapSimulation.xml @@ -19,9 +19,9 @@ - - - + + + @@ -147,11 +147,11 @@ - + - - + - + + + + diff --git a/Kassiopeia/XML/Examples/VTK/AnalyticSimulation.xml b/Kassiopeia/XML/Examples/VTK/AnalyticSimulation.xml index 63820ebb3..20dda9d49 100644 --- a/Kassiopeia/XML/Examples/VTK/AnalyticSimulation.xml +++ b/Kassiopeia/XML/Examples/VTK/AnalyticSimulation.xml @@ -12,21 +12,21 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + @@ -63,18 +63,18 @@ - + - - + + + + diff --git a/Kassiopeia/XML/Examples/VTK/DipoleTrapMeshedSpaceSimulation.xml b/Kassiopeia/XML/Examples/VTK/DipoleTrapMeshedSpaceSimulation.xml index 2990061ae..1e72d1b9e 100644 --- a/Kassiopeia/XML/Examples/VTK/DipoleTrapMeshedSpaceSimulation.xml +++ b/Kassiopeia/XML/Examples/VTK/DipoleTrapMeshedSpaceSimulation.xml @@ -186,11 +186,11 @@ - + - - + - - + - + + + + diff --git a/Kassiopeia/XML/Examples/VTK/DipoleTrapSimulation.xml b/Kassiopeia/XML/Examples/VTK/DipoleTrapSimulation.xml index ac157da1c..e5518d470 100644 --- a/Kassiopeia/XML/Examples/VTK/DipoleTrapSimulation.xml +++ b/Kassiopeia/XML/Examples/VTK/DipoleTrapSimulation.xml @@ -141,11 +141,11 @@ - + - - + - - + - + + + + diff --git a/Kassiopeia/XML/Examples/VTK/MeshSimulation.xml b/Kassiopeia/XML/Examples/VTK/MeshSimulation.xml new file mode 100644 index 000000000..534201c46 --- /dev/null +++ b/Kassiopeia/XML/Examples/VTK/MeshSimulation.xml @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Kassiopeia/XML/Examples/VTK/PhotoMultiplierTubeSimulation.xml b/Kassiopeia/XML/Examples/VTK/PhotoMultiplierTubeSimulation.xml index 4153ced3c..65fc37275 100644 --- a/Kassiopeia/XML/Examples/VTK/PhotoMultiplierTubeSimulation.xml +++ b/Kassiopeia/XML/Examples/VTK/PhotoMultiplierTubeSimulation.xml @@ -18,7 +18,7 @@ - + @@ -325,12 +325,11 @@ - - + - - + + + + diff --git a/Kassiopeia/XML/Examples/VTK/QuadrupoleTrapSimulation.xml b/Kassiopeia/XML/Examples/VTK/QuadrupoleTrapSimulation.xml index 02b7f4c8d..c7edf6b27 100644 --- a/Kassiopeia/XML/Examples/VTK/QuadrupoleTrapSimulation.xml +++ b/Kassiopeia/XML/Examples/VTK/QuadrupoleTrapSimulation.xml @@ -13,21 +13,21 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + @@ -139,11 +139,11 @@ - + - - + - - + + + + + @@ -367,9 +371,9 @@ - + - + diff --git a/Kassiopeia/XML/Examples/VTK/ToricTrapSimulation.xml b/Kassiopeia/XML/Examples/VTK/ToricTrapSimulation.xml index f3e3cb8f2..c035fbddc 100644 --- a/Kassiopeia/XML/Examples/VTK/ToricTrapSimulation.xml +++ b/Kassiopeia/XML/Examples/VTK/ToricTrapSimulation.xml @@ -19,16 +19,16 @@ - - - + + + - + @@ -147,40 +147,11 @@ - - - - - - + - - + - + + + + @@ -387,3 +362,42 @@ /> + + + + + + + diff --git a/Kommon/Boost/CMakeLists.txt b/Kommon/Boost/CMakeLists.txt index 88e63b9d9..9d6f374fb 100644 --- a/Kommon/Boost/CMakeLists.txt +++ b/Kommon/Boost/CMakeLists.txt @@ -1,5 +1,4 @@ # include directories -kasper_internal_include_directories( Utility ) # headers set(KOMMON_BOOST_HEADER_FILES diff --git a/Kommon/Boost/Utility/KStringUtils.h b/Kommon/Boost/Utility/KStringUtils.h index 6f10b470a..cdbed42fb 100644 --- a/Kommon/Boost/Utility/KStringUtils.h +++ b/Kommon/Boost/Utility/KStringUtils.h @@ -58,6 +58,10 @@ class KStringUtils template static bool IContainsOneOf(const Range1T&, std::initializer_list); + template static bool StartsWith(const Range1T&, const Range2T&); + + template static bool IStartsWith(const Range1T&, const Range2T&); + template static size_t Distance(const Range1T&, const Range2T&); template static size_t IDistance(const Range1T&, const Range2T&); @@ -99,6 +103,10 @@ class KStringUtils static std::string RandomAlphaNum(size_t length); + static void HexDump(const void* data, size_t length, std::ostream& os = std::cout); + template + static void HexDump(const SequenceT& data, std::ostream& os = std::cout); + private: template static size_t LevenshteinDistance(const Range1T&, const Range2T&); }; @@ -239,6 +247,16 @@ inline bool KStringUtils::IContainsOneOf(const Range1T& r1, std::initializer_lis return false; } +template inline bool KStringUtils::StartsWith(const Range1T& r1, const Range2T& r2) +{ + return boost::starts_with(r1, r2); +} + +template inline bool KStringUtils::IStartsWith(const Range1T& r1, const Range2T& r2) +{ + return boost::istarts_with(r1, r2); +} + template inline size_t KStringUtils::Distance(const Range1T& r1, const Range2T& r2) { return LevenshteinDistance(r1, r2); @@ -462,6 +480,55 @@ inline std::string KStringUtils::RandomAlphaNum(size_t length) return result; } +// adapted from +inline void KStringUtils::HexDump(const void *data, size_t length, std::ostream& os) +{ + size_t i; + unsigned char linebuf[17]; + unsigned char *pc = (unsigned char*)data; + + // Process every byte in the data. + for (i = 0; i < length; i++) { + // Multiple of 16 means new line (with line offset). + + if ((i % 16) == 0) { + // Just don't print ASCII for the zeroth line. + if (i != 0) + os << " " << linebuf << "\n"; + + // Output the offset. + os << " " << std::hex << std::setfill('0') << std::setw(4) << i; + } + + // Now the hex code for the specific character. + os << " " << std::hex << std::setfill('0') << std::setw(2) << pc[i]; + + // And store a printable ASCII character for later. + if ((pc[i] < 0x20) || (pc[i] > 0x7e)) { + linebuf[i % 16] = '.'; + } else { + linebuf[i % 16] = pc[i]; + } + + linebuf[(i % 16) + 1] = '\0'; + } + + // Pad out last line if not exactly 16 characters. + while ((i % 16) != 0) { + os << " "; + i++; + } + + // And print the final ASCII bit. + os << " " << linebuf << "\n"; +} + +template +inline void KStringUtils::HexDump(const SequenceT& sequence, std::ostream& os) +{ + HexDump(sequence.data(), sequence.size() * sizeof(typename SequenceT::value_type), os); +} + } // namespace katrin diff --git a/Kommon/CMakeLists.txt b/Kommon/CMakeLists.txt index ceeb3364f..d9bc0ba5f 100644 --- a/Kommon/CMakeLists.txt +++ b/Kommon/CMakeLists.txt @@ -2,30 +2,23 @@ cmake_minimum_required( VERSION ${CMAKE_MINIMUM_VERSION} ) # Kommon version set( MODULE_VERSION_MAJOR 1 ) -set( MODULE_VERSION_MINOR 4 ) -set( MODULE_VERSION_PATCH 2 ) +set( MODULE_VERSION_MINOR 5 ) +set( MODULE_VERSION_PATCH 0 ) set( MODULE_VERSION "${MODULE_VERSION_MAJOR}.${MODULE_VERSION_MINOR}.${MODULE_VERSION_PATCH}" ) #project( Kommon VERSION ${MODULE_VERSION} ) project( Kommon ) -#set( CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake ${PROJECT_SOURCE_DIR}/GoogleTest/cmake ) include( KasperDefaults ) - # paths kasper_module_paths( Kommon ) # debugging kasper_module_debug() -#if( Kommon_ENABLE_DEBUG ) -# add_cflag (Kommon_ENABLE_DEBUG) -#endif() - -set(EXTERNAL_LIBRARIES) # external -find_package( Log4CXX ) +find_package( LOG4CXX ) if(LOG4CXX_FOUND) option( Kommon_USE_Log4CXX "Enable advanced logging facilities, if LOG4CXX library is available." ON ) endif() @@ -36,8 +29,6 @@ if(Kommon_USE_Log4CXX) set_source_files_properties(Core/Logging/KLogger.cxx PROPERTIES COMPILE_DEFINITIONS "LOG4CXX;LOGGER_CONFIGURATION=${LOGGER_CONFIGURATION}" ) - kasper_external_include_directories( ${LOG4CXX_INCLUDE_DIR} ) - list(APPEND EXTERNAL_LIBRARIES ${LOG4CXX_LIBRARY} ) endif() option( KLogger_THROW_EXCEPTIONS "Throw exception when using KERROR/KFATAL macros." OFF ) @@ -58,48 +49,91 @@ add_subdirectory( cmake ) add_subdirectory( Documentation ) if( KASPER_USE_BOOST ) - find_package( Boost 1.43.0 COMPONENTS filesystem REQUIRED ) - if( Boost_INCLUDE_DIR ) - kasper_external_include_directories( ${Boost_INCLUDE_DIR} ) - list(APPEND EXTERNAL_LIBRARIES ${Boost_LIBRARIES} ) - else() - list(APPEND EXTERNAL_LIBRARIES Boost::headers Boost::filesystem ) - endif() - add_compile_definitions( KASPER_USE_BOOST ) + find_package( Boost ${BOOST_MINIMUM_VERSION} REQUIRED COMPONENTS filesystem system ) add_subdirectory( Boost ) endif() if( KASPER_USE_ROOT ) - find_package( ROOT 5.24.0 REQUIRED ) - kasper_external_include_directories( ${ROOT_INCLUDE_DIR} ) - add_definitions( -DKommon_USE_ROOT ) - list(APPEND EXTERNAL_LIBRARIES ${ROOT_LIBRARIES} ) - add_compile_definitions( KASPER_USE_ROOT ) + find_package( ROOT ${ROOT_MINIMUM_VERSION} CONFIG REQUIRED ) add_subdirectory( Root ) endif() if( KASPER_USE_GSL ) find_package( GSL REQUIRED ) - kasper_external_include_directories( ${GSL_INCLUDE_DIRS} ) - list(APPEND EXTERNAL_LIBRARIES ${GSL_LIBRARIES} ) - add_compile_definitions( KASPER_USE_GSL ) add_subdirectory( Gsl ) endif() if( KASPER_USE_TBB ) find_package( TBB REQUIRED ) - kasper_external_include_directories( ${TBB_INCLUDE_DIR} ) - add_compile_definitions( KASPER_USE_TBB ) add_subdirectory( TBB ) endif() add_subdirectory( Core ) +add_subdirectory( Core/Binning ) +add_subdirectory( Core/Maths ) + +# Fix build issues for certain source files +#set_property(SOURCE Core/Initialization/KVariant.cxx APPEND PROPERTY COMPILE_DEFINITIONS __GLIBCXX_USE_CXX11_ABI=0) +set_property(SOURCE Core/Initialization/tinyexpr.c APPEND PROPERTY COMPILE_OPTIONS "-Wno-array-bounds" ) # FIXME -kasper_include_default_dirs() kasper_install_headers( ${KOMMON_HEADER_FILES} ) -add_library( Kommon SHARED ${KOMMON_SOURCE_FILES} ${KOMMON_HEADER_FILES} ) -target_link_libraries( Kommon ${EXTERNAL_LIBRARIES} ) +add_library( Kommon SHARED + ${KOMMON_SOURCE_FILES} ${KOMMON_HEADER_FILES} ) + +# get header paths from collected header files +foreach(HEADER ${KOMMON_HEADER_FILES}) + get_filename_component(DIRNAME ${HEADER} DIRECTORY) + target_include_directories(Kommon PUBLIC $) +endforeach(HEADER) +target_include_directories(Kommon PUBLIC $) + +if( KASPER_USE_BOOST ) + target_compile_definitions(Kommon PUBLIC KASPER_USE_BOOST) + target_link_libraries(Kommon + PUBLIC + Boost::boost + Boost::system + PRIVATE + Boost::filesystem + ) +endif( KASPER_USE_BOOST ) + +if( KASPER_USE_ROOT ) + target_compile_definitions(Kommon PUBLIC KASPER_USE_ROOT) + target_link_libraries( Kommon + PUBLIC + ROOT::Core ROOT::Graf ROOT::Gpad ROOT::Hist + PRIVATE + ROOT::MathCore + ) +endif(KASPER_USE_ROOT) + +if( KASPER_USE_GSL ) + target_compile_definitions(Kommon PUBLIC KASPER_USE_GSL) + target_link_libraries(Kommon + PRIVATE + GSL::gsl + ) +endif(KASPER_USE_GSL) + +if( KASPER_USE_TBB ) + target_include_directories(Kommon PRIVATE ${TBB_INCLUDE_DIRS}) + target_compile_definitions(Kommon PUBLIC KASPER_USE_TBB) + target_link_libraries(Kommon + PRIVATE + ${TBB_LIBRARIES} + ) +endif( KASPER_USE_TBB ) + +if( Kommon_USE_Log4CXX ) + target_include_directories( Kommon PRIVATE ${LOG4CXX_INCLUDE_DIR}) + target_link_libraries( Kommon + PRIVATE + ${LOG4CXX_LIBRARY} + ) +endif(Kommon_USE_Log4CXX) + kasper_install_libraries( Kommon ) # a distinct shared library "KommonVtk" is built here! diff --git a/Kommon/Core/Binning/BinningConfig.cmake b/Kommon/Core/Binning/BinningConfig.cmake.in similarity index 100% rename from Kommon/Core/Binning/BinningConfig.cmake rename to Kommon/Core/Binning/BinningConfig.cmake.in diff --git a/Kommon/Core/Binning/BinningConfigVersion.cmake.in b/Kommon/Core/Binning/BinningConfigVersion.cmake.in new file mode 100644 index 000000000..25f052f29 --- /dev/null +++ b/Kommon/Core/Binning/BinningConfigVersion.cmake.in @@ -0,0 +1,11 @@ +set(PACKAGE_VERSION "@MODULE_VERSION@") + +# Check whether the requested PACKAGE_FIND_VERSION is compatible +if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() diff --git a/Kommon/Core/Binning/CMakeLists.txt b/Kommon/Core/Binning/CMakeLists.txt index 766e35fa3..41ed905d7 100644 --- a/Kommon/Core/Binning/CMakeLists.txt +++ b/Kommon/Core/Binning/CMakeLists.txt @@ -1,44 +1,38 @@ -cmake_minimum_required(VERSION 3.8) +cmake_minimum_required(VERSION ${CMAKE_MINIMUM_VERSION}) project(Binning) +kasper_module_paths(Kommon) + # dependencies -find_package(Boost 1.58 REQUIRED) +find_package(Boost ${BOOST_MINIMUM_VERSION} REQUIRED) # headers set(HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/include/ + ${CMAKE_CURRENT_SOURCE_DIR}/include/ ) # sources set(SOURCE_BASENAMES - ConstantBinning.cpp - VariableBinning.cpp + ConstantBinning.cpp + VariableBinning.cpp ) foreach(BASENAME ${SOURCE_BASENAMES}) - list(APPEND SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/${BASENAME}) + list(APPEND SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/${BASENAME}) endforeach(BASENAME) # library -add_library(${PROJECT_NAME} SHARED ${SOURCES}) -target_include_directories(${PROJECT_NAME} - PUBLIC $ $ - PRIVATE ${Boost_INCLUDE_DIRS} +add_library(Binning SHARED ${SOURCES}) +target_include_directories(Binning + PUBLIC $ $ ) -target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14) -target_link_libraries(${PROJECT_NAME}) - -# install headers and lib -#include(GNUInstallDirs) -install(DIRECTORY ${HEADER_PATH} DESTINATION ${INCLUDE_INSTALL_DIR}) -install(TARGETS ${PROJECT_NAME} - EXPORT ${PROJECT_NAME}Targets - DESTINATION ${LIB_INSTALL_DIR} +target_compile_features(Binning PRIVATE cxx_std_14) +target_link_libraries(Binning + PRIVATE + Kommon + Boost::boost ) -# install CMake Targets and Config -install(EXPORT ${PROJECT_NAME}Targets - NAMESPACE ${PROJECT_NAME}:: - DESTINATION ${CMAKE_INSTALL_DIR}/${PROJECT_NAME} -) -install(FILES ${PROJECT_NAME}Config.cmake DESTINATION ${CMAKE_INSTALL_DIR}/${PROJECT_NAME}) +kasper_install_libraries(Binning) + +kasper_install_module() diff --git a/Kommon/Core/CMakeLists.txt b/Kommon/Core/CMakeLists.txt index 0aa7b637e..aa74195c5 100644 --- a/Kommon/Core/CMakeLists.txt +++ b/Kommon/Core/CMakeLists.txt @@ -1,31 +1,18 @@ -# include directories -kasper_internal_include_directories( - Binning/include - Functions - Geometry - Logging - File - Initialization - Maths - Random - Typelists - Units - Utility - ../Extensions/Root/Initialization -) - # headers set(KOMMON_CORE_HEADER_FILES Typelists/KTypeNull.h Typelists/KTypeList.h Typelists/KTypeChain.h Typelists/KTypeOperation.h + Units/KDimensions.h Units/KUnits.h + File/KFileMessage.h File/KFile.h File/KTextFile.h File/KPathResolver.h + Initialization/KInitializationMessage.hh Initialization/KToken.hh Initialization/KTypedTokens.hh @@ -49,13 +36,15 @@ set(KOMMON_CORE_HEADER_FILES Initialization/KElementProcessor.hh Initialization/KVariant.h Initialization/KArgumentList.h + Initialization/KXMLInitializer.hh + Random/KNamedRandomGenerator.h Random/KNamedRandomPrototype.h Random/KRandomBuilder.h Random/KNamedRandomGeneratorBuilder.h Random/KRandom.h Random/KRandomPrototype.h - Initialization/KXMLInitializer.hh + Utility/Gnuplot.hpp Utility/KAlgorithm.h Utility/KException.h @@ -103,6 +92,7 @@ set(KOMMON_CORE_HEADER_FILES Utility/PositiveValue.h Utility/Printable.h Utility/SimplyPrintableCollection.h + Logging/KLogger.h ) @@ -112,6 +102,7 @@ set(KOMMON_CORE_SOURCE_FILES File/KFile.cxx File/KTextFile.cxx File/KPathResolver.cxx + Initialization/KInitializationMessage.cc Initialization/KToken.cc Initialization/KProcessor.cc @@ -132,11 +123,15 @@ set(KOMMON_CORE_SOURCE_FILES Initialization/KVariant.cxx Initialization/KArgumentList.cxx Initialization/KXMLInitializer.cc + Units/KDimensions.cxx Units/KUnits.cxx + Utility/Gnuplot.cpp + Random/KRandomBuilder.cxx Random/KNamedRandomGeneratorBuilder.cxx + Utility/KMessage.cxx Utility/KUtilityMessage.cxx Utility/KNamed.cxx @@ -151,6 +146,7 @@ set(KOMMON_CORE_SOURCE_FILES Utility/KMessageBuilder.cxx Utility/KNamedBuilder.cxx Utility/Printable.cxx + Logging/KLogger.cxx ) @@ -160,9 +156,6 @@ set(KOMMON_CORE_EXTRA_FILES Initialization/tinyexpr.h ) - -set_source_files_properties(Initialization/KVariant.cxx PROPERTIES COMPILE_DEFINITIONS __GLIBCXX_USE_CXX11_ABI=0) - if( LOG4CXX_FOUND ) if (NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE MATCHES "DEBUG" OR CMAKE_BUILD_TYPE MATCHES "RELWITHDEBINFO" ) set (LEVEL "DEBUG") @@ -177,6 +170,3 @@ endif() # propagate path variable to parent scope kasper_append_paths( KOMMON_HEADER_FILES ${KOMMON_CORE_HEADER_FILES} ) kasper_append_paths( KOMMON_SOURCE_FILES ${KOMMON_CORE_SOURCE_FILES} ${KOMMON_CORE_EXTRA_FILES}) - -add_subdirectory(Binning) -add_subdirectory(Maths) diff --git a/Kommon/Core/File/KPathResolver.cxx b/Kommon/Core/File/KPathResolver.cxx index 3f857e287..b476e0144 100644 --- a/Kommon/Core/File/KPathResolver.cxx +++ b/Kommon/Core/File/KPathResolver.cxx @@ -7,6 +7,8 @@ #include #include +#include + using namespace std; namespace diff --git a/Kommon/Core/File/KPathResolver.h b/Kommon/Core/File/KPathResolver.h index 4883d030c..19b85465a 100644 --- a/Kommon/Core/File/KPathResolver.h +++ b/Kommon/Core/File/KPathResolver.h @@ -32,8 +32,8 @@ class KPathResolver virtual ~KPathResolver(); virtual std::string GetDirectory(KEDirectory directory) const; + virtual std::string ResolvePath(const std::string& filename, KEDirectory directory = KEDirectory::Undefined) const; - std::string ResolvePath(const std::string& filename, KEDirectory directory = KEDirectory::Undefined) const; std::vector getAllFileNames(std::string directoryPath) const; std::vector getAllFilesContaining(std::string NamePattern) const; }; diff --git a/Kommon/Core/Initialization/KVariant.h b/Kommon/Core/Initialization/KVariant.h index e59e31c41..51f19b1c8 100644 --- a/Kommon/Core/Initialization/KVariant.h +++ b/Kommon/Core/Initialization/KVariant.h @@ -272,7 +272,7 @@ template<> struct KVariantDecoder int compare(const KVariant& id1, const KVariant& id2); -KVariant::KVariant() : fType(Type_Void) {} +KVariant::KVariant() : fType(Type_Void), fPrimitive() {} KVariant::KVariant(bool Value) : fType(Type_Bool) { diff --git a/Kommon/Core/Initialization/KXMLInitializer.cc b/Kommon/Core/Initialization/KXMLInitializer.cc index e042126ba..e2be39770 100644 --- a/Kommon/Core/Initialization/KXMLInitializer.cc +++ b/Kommon/Core/Initialization/KXMLInitializer.cc @@ -16,7 +16,7 @@ #include -#ifdef Kommon_USE_ROOT +#ifdef KASPER_USE_ROOT #include "KFormulaProcessor.hh" #endif @@ -34,7 +34,8 @@ KXMLInitializer::KXMLInitializer() : fConfigSerializer(), fTokenizer(nullptr), fArguments(), - fVerbosityLevel(eNormal), + fVerbosityLevel(0), + fBatchMode(false), fDefaultConfigFile(), fDefaultIncludePaths(), fAllowConfigFileFallback(false), @@ -45,7 +46,8 @@ KXMLInitializer::~KXMLInitializer() = default; void KXMLInitializer::ParseCommandLine(int argc, char** argv) { - fVerbosityLevel = eNormal; // reset + fVerbosityLevel = 0; // reset + fBatchMode = false; KArgumentList commandLineArgs; if (argc >= 1) { @@ -89,18 +91,21 @@ void KXMLInitializer::ParseCommandLine(int argc, char** argv) if (key.length() > 0 && key[0] == '-') { // parse verbosity options like '-vvqv -q -vv' if (key.length() >= 2 && (key[1] == 'v' || key[1] == 'q')) { - int verbosity = 0; + int verbosityAdjust = 0; for (size_t i = 1; i < key.length(); i++) { if (key[i] == 'v') - verbosity++; + verbosityAdjust++; else if (key[i] == 'q') - verbosity--; + verbosityAdjust--; else { - verbosity = 0; + verbosityAdjust = 0; break; } } - fVerbosityLevel += verbosity; + fVerbosityLevel += verbosityAdjust; + } + else if (key == string("-b") || key == string("-batch")) { + fBatchMode = true; } // treat as key=value pair @@ -240,7 +245,7 @@ void KXMLInitializer::SetupProcessChain(const map& variables, co } tIncludeProcessor->InsertAfter(tVariableProcessor); -#ifdef Kommon_USE_ROOT +#ifdef KASPER_USE_ROOT auto* tFormulaProcessor = new KFormulaProcessor(); tFormulaProcessor->InsertAfter(tVariableProcessor); tIncludeProcessor->InsertAfter(tFormulaProcessor); @@ -273,8 +278,10 @@ KXMLTokenizer* KXMLInitializer::Configure(int argc, char** argv, bool processCon ParseCommandLine(argc, argv); initmsg(eNormal) << "Command line: " << fArguments.CommandLine() << eom; - KDEBUG("Verbosity level is now: " << fVerbosityLevel); - KMessageTable::GetInstance().SetTerminalVerbosity(static_cast(fVerbosityLevel)); + if (fVerbosityLevel != 0) + KINFO("Verbosity level " << (fVerbosityLevel < 0 ? "decreased" : "increased") << " by " << fVerbosityLevel); + KLoggerTable::GetInstance().SetVerbosityLevel(fVerbosityLevel); + KMessageTable::GetInstance().SetVerbosityLevel(fVerbosityLevel); KMessageTable::GetInstance().SetShowShutdownMessage(); pair tConfig; diff --git a/Kommon/Core/Initialization/KXMLInitializer.hh b/Kommon/Core/Initialization/KXMLInitializer.hh index 5956dafce..073c6a73c 100644 --- a/Kommon/Core/Initialization/KXMLInitializer.hh +++ b/Kommon/Core/Initialization/KXMLInitializer.hh @@ -47,12 +47,20 @@ class KXMLInitializer : public KSingleton { return fVerbosityLevel; } + bool IsBatchMode() const + { + return fBatchMode; + } const KXMLTokenizer* GetContext() const { return fTokenizer; } + const std::string GetSerializedConfig() const { + return fConfigSerializer ? fConfigSerializer->GetConfig() : ""; + } + KXMLTokenizer* Configure(int argc = 0, char** argv = nullptr, bool processConfig = true); void UpdateVariables(const KArgumentList& args); @@ -71,6 +79,7 @@ class KXMLInitializer : public KSingleton KXMLTokenizer* fTokenizer; KArgumentList fArguments; int fVerbosityLevel; + bool fBatchMode; std::string fDefaultConfigFile; std::vector fDefaultIncludePaths; bool fAllowConfigFileFallback; diff --git a/Kommon/Core/Initialization/tinyexpr.c b/Kommon/Core/Initialization/tinyexpr.c index 4facfbcca..a5fc9d8ef 100644 --- a/Kommon/Core/Initialization/tinyexpr.c +++ b/Kommon/Core/Initialization/tinyexpr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Zlib /* * TINYEXPR - Tiny recursive descent parser and evaluation engine in C * @@ -39,6 +40,7 @@ For log = natural log uncomment the next line. */ #include #include #include +#include #include #ifndef NAN @@ -242,11 +244,11 @@ void next_token(state *s) { s->type = TOK_NUMBER; } else { /* Look for a variable or builtin function call. */ - if (s->next[0] >= 'a' && s->next[0] <= 'z') { + if (isalpha(s->next[0])) { const char *start; start = s->next; - while ((s->next[0] >= 'a' && s->next[0] <= 'z') || (s->next[0] >= '0' && s->next[0] <= '9') || (s->next[0] == '_')) s->next++; - + while (isalpha(s->next[0]) || isdigit(s->next[0]) || (s->next[0] == '_')) s->next++; + const te_variable *var = find_lookup(s, start, s->next - start); if (!var) var = find_builtin(start, s->next - start); diff --git a/Kommon/Core/Initialization/tinyexpr.h b/Kommon/Core/Initialization/tinyexpr.h index c9afa6c35..c2cbe1a30 100644 --- a/Kommon/Core/Initialization/tinyexpr.h +++ b/Kommon/Core/Initialization/tinyexpr.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Zlib /* * TINYEXPR - Tiny recursive descent parser and evaluation engine in C * diff --git a/Kommon/Core/Logging/KLogger.cxx b/Kommon/Core/Logging/KLogger.cxx index b0436182a..6fefb5439 100644 --- a/Kommon/Core/Logging/KLogger.cxx +++ b/Kommon/Core/Logging/KLogger.cxx @@ -9,24 +9,21 @@ #include "KException.h" -#ifdef KLOGGER_THROW_EXCEPTIONS -#pragma message "KLogger will throw exceptions on error" -#include "KException.h" -#endif - #include #include #include +#include using namespace std; using namespace katrin; static const char* skEndColor = COLOR_PREFIX COLOR_NORMAL COLOR_SUFFIX; -static const char* skFatalColor = COLOR_PREFIX COLOR_BRIGHT COLOR_SEPARATOR COLOR_FOREGROUND_RED COLOR_SUFFIX; +static const char* skFatalColor = COLOR_PREFIX COLOR_BRIGHT COLOR_SEPARATOR COLOR_FOREGROUND_PURPLE COLOR_SUFFIX; static const char* skErrorColor = COLOR_PREFIX COLOR_BRIGHT COLOR_SEPARATOR COLOR_FOREGROUND_RED COLOR_SUFFIX; static const char* skWarnColor = COLOR_PREFIX COLOR_BRIGHT COLOR_SEPARATOR COLOR_FOREGROUND_YELLOW COLOR_SUFFIX; static const char* skInfoColor = COLOR_PREFIX COLOR_BRIGHT COLOR_SEPARATOR COLOR_FOREGROUND_GREEN COLOR_SUFFIX; static const char* skDebugColor = COLOR_PREFIX COLOR_BRIGHT COLOR_SEPARATOR COLOR_FOREGROUND_CYAN COLOR_SUFFIX; +static const char* skTraceColor = COLOR_PREFIX COLOR_BRIGHT COLOR_SEPARATOR COLOR_FOREGROUND_BLUE COLOR_SUFFIX; static const char* skOtherColor = COLOR_PREFIX COLOR_BRIGHT COLOR_SEPARATOR COLOR_FOREGROUND_WHITE COLOR_SUFFIX; namespace @@ -44,8 +41,9 @@ inline const char* level2Color(KLogger::ELevel level) case KLogger::eInfo: return skInfoColor; case KLogger::eDebug: - case KLogger::eTrace: return skDebugColor; + case KLogger::eTrace: + return skTraceColor; default: return skOtherColor; } @@ -236,7 +234,8 @@ const string& KLogger::GetName() const bool KLogger::IsLevelEnabled(ELevel level) const { - return fPrivate->fLogger->isEnabledFor(level2Ptr(level)); + ELevel displayedLevel = KLoggerTable::GetInstance().CorrectedLevel(level); + return fPrivate->fLogger->isEnabledFor(level2Ptr(displayedLevel)) || level >= eFatal; } KLogger::ELevel KLogger::GetLevel() const @@ -253,10 +252,12 @@ void KLogger::Log(ELevel level, const string& message, const Location& loc) { fPrivate->log(level2Ptr(level), message, loc); - if (level == ELevel::eFatal) + if (level >= eFatal) { throw KException() << "fatal error in " << loc.fFunctionName; + exit(EXIT_FAILURE); + } #ifdef KLOGGER_THROW_EXCEPTIONS - if (level >= ELevel::eError) + else if (level >= ELevel::eError) throw KException() << "error in " << loc.fFunctionName; #endif } @@ -392,7 +393,8 @@ const string& KLogger::GetName() const bool KLogger::IsLevelEnabled(ELevel level) const { - return fPrivate->fLogLevel <= level; + ELevel displayedLevel = KLoggerTable::GetInstance().CorrectedLevel(level); + return fPrivate->fLogLevel <= displayedLevel || level >= eFatal; } KLogger::ELevel KLogger::GetLevel() const @@ -419,16 +421,18 @@ void KLogger::Log(ELevel level, const string& message, const Location& loc) fPrivate->logCerr(levelStr, message, loc, color); #endif - if (level == ELevel::eFatal) + if (level >= eFatal) { throw KException() << "fatal error in " << loc.fFunctionName; + exit(EXIT_FAILURE); + } #ifdef KLOGGER_THROW_EXCEPTIONS - if (level >= eError) + else if (level >= eError) throw KException() << "error in " << loc.fFunctionName; #endif } #endif // LOG4CXX -KLoggerTable::KLoggerTable() : fLoggerMap() {} +KLoggerTable::KLoggerTable() : fLoggerMap(), fVerbosityLevel(0) {} KLoggerTable::~KLoggerTable() = default; @@ -474,3 +478,19 @@ void KLoggerTable::SetLevel(const KLogger::ELevel& level, const string& name) logger->SetLevel(level); } } + +void KLoggerTable::SetVerbosityLevel(int level) +{ + fVerbosityLevel = level; +} + +KLogger::ELevel KLoggerTable::CorrectedLevel(KLogger::ELevel level) const +{ + // larger value means higher message severity + auto result = static_cast(level + fVerbosityLevel); + if (result <= KLogger::eTrace) + return KLogger::eTrace; + else if (result >= KLogger::eFatal) + return KLogger::eFatal; + return result; +} diff --git a/Kommon/Core/Logging/KLogger.h b/Kommon/Core/Logging/KLogger.h index 5448f9f4e..56c9fbb31 100644 --- a/Kommon/Core/Logging/KLogger.h +++ b/Kommon/Core/Logging/KLogger.h @@ -42,6 +42,8 @@ #define COLOR_FOREGROUND_RED "31" #define COLOR_FOREGROUND_GREEN "32" #define COLOR_FOREGROUND_YELLOW "33" +#define COLOR_FOREGROUND_BLUE "34" +#define COLOR_FOREGROUND_PURPLE "35" #define COLOR_FOREGROUND_CYAN "36" #define COLOR_FOREGROUND_WHITE "37" #define COLOR_PREFIX "\033[" @@ -107,9 +109,9 @@ namespace katrin class KLogger { public: - enum ELevel + enum ELevel : int { - eTrace, + eTrace = 0, eDebug, eInfo, eWarn, @@ -120,9 +122,9 @@ class KLogger public: /** - * A simple struct used by the Logger macros to pass information about the filename and line number. - * Not to be used directly by the user! - */ + * A simple struct used by the Logger macros to pass information about the filename and line number. + * Not to be used directly by the user! + */ struct Location { Location(const char* const fileName = "", const char* const functionName = "", int lineNumber = -1) : @@ -137,9 +139,9 @@ class KLogger public: /** - * Standard constructor assigning a name to the logger instance. - * @param name The logger name. - */ + * Standard constructor assigning a name to the logger instance. + * @param name The logger name. + */ KLogger(const char* name = nullptr); /// @overload KLogger(const std::string& name); @@ -148,96 +150,96 @@ class KLogger virtual ~KLogger(); /** - * Get a loggers name - * @return name identifiying the logger - */ + * Get a loggers name + * @return name identifiying the logger + */ const std::string& GetName() const; /** - * Check whether a certain log-level is enabled. - * @param level The log level as string representation. - * @return - */ + * Check whether a certain log-level is enabled. + * @param level The log level as string representation. + * @return + */ bool IsLevelEnabled(ELevel level) const; /** - * Get a loggers minimum logging level - * @return level enum item identifying the log level - */ + * Get a loggers minimum logging level + * @return level enum item identifying the log level + */ ELevel GetLevel() const; /** - * Set a loggers minimum logging level - * @param level enum item identifying the log level - */ + * Set a loggers minimum logging level + * @param level enum item identifying the log level + */ void SetLevel(ELevel level); /** - * Log a message with the specified level. - * Use the macro KLOG(logger, level, message). - * @param level The log level. - * @param message The message. - * @param loc Source code location (set automatically by the corresponding macro). - */ + * Log a message with the specified level. + * Use the macro KLOG(logger, level, message). + * @param level The log level. + * @param message The message. + * @param loc Source code location (set automatically by the corresponding macro). + */ void Log(ELevel level, const std::string& message, const Location& loc = Location()); /** - * Log a message at TRACE level. - * Use the macro KTRACE(logger, message). - * @param message The message. - * @param loc Source code location (set automatically by the corresponding macro). - */ + * Log a message at TRACE level. + * Use the macro KTRACE(logger, message). + * @param message The message. + * @param loc Source code location (set automatically by the corresponding macro). + */ void LogTrace(const std::string& message, const Location& loc = Location()) { Log(eTrace, message, loc); } /** - * Log a message at DEBUG level. - * Use the macro KDEBUG(logger, message). - * @param message The message. - * @param loc Source code location (set automatically by the corresponding macro). - */ + * Log a message at DEBUG level. + * Use the macro KDEBUG(logger, message). + * @param message The message. + * @param loc Source code location (set automatically by the corresponding macro). + */ void LogDebug(const std::string& message, const Location& loc = Location()) { Log(eDebug, message, loc); } /** - * Log a message at DEBUG level. - * Use the macro KDEBUG(logger, message). - * @param message The message. - * @param loc Source code location (set automatically by the corresponding macro). - */ + * Log a message at DEBUG level. + * Use the macro KDEBUG(logger, message). + * @param message The message. + * @param loc Source code location (set automatically by the corresponding macro). + */ void LogInfo(const std::string& message, const Location& loc = Location()) { Log(eInfo, message, loc); } /** - * Log a message at INFO level. - * Use the macro KINFO(logger, message). - * @param message The message. - * @param loc Source code location (set automatically by the corresponding macro). - */ + * Log a message at INFO level. + * Use the macro KINFO(logger, message). + * @param message The message. + * @param loc Source code location (set automatically by the corresponding macro). + */ void LogWarn(const std::string& message, const Location& loc = Location()) { Log(eWarn, message, loc); } /** - * Log a message at ERROR level. - * Use the macro KERROR(logger, message). - * @param message The message. - * @param loc Source code location (set automatically by the corresponding macro). - */ + * Log a message at ERROR level. + * Use the macro KERROR(logger, message). + * @param message The message. + * @param loc Source code location (set automatically by the corresponding macro). + */ void LogError(const std::string& message, const Location& loc = Location()) { Log(eError, message, loc); } /** - * Log a message at FATAL level. - * Use the macro KFATAL(logger, message). - * @note This will throw a KException after the error message. - * @param message The message. - * @param loc Source code location (set automatically by the corresponding macro). - */ + * Log a message at FATAL level. + * Use the macro KFATAL(logger, message). + * @note This will throw a KException after the error message. + * @param message The message. + * @param loc Source code location (set automatically by the corresponding macro). + */ void LogFatal(const std::string& message, const Location& loc = Location()) { Log(eFatal, message, loc); @@ -273,6 +275,9 @@ class KLoggerTable : public KSingleton void SetLevel(const KLogger::ELevel& level); void SetLevel(const KLogger::ELevel& level, const std::string& name); + void SetVerbosityLevel(int offset = 0); + KLogger::ELevel CorrectedLevel(KLogger::ELevel level) const; + private: using LoggerMap = std::map>; using LoggerEntry = LoggerMap::value_type; @@ -280,6 +285,7 @@ class KLoggerTable : public KSingleton using LoggerCIt = LoggerMap::const_iterator; LoggerMap fLoggerMap; + int fVerbosityLevel; }; } // namespace katrin diff --git a/Kommon/Core/Maths/CMakeLists.txt b/Kommon/Core/Maths/CMakeLists.txt index 76b19b0db..5d756afe1 100644 --- a/Kommon/Core/Maths/CMakeLists.txt +++ b/Kommon/Core/Maths/CMakeLists.txt @@ -1,12 +1,14 @@ -cmake_minimum_required(VERSION 3.8) +cmake_minimum_required(VERSION ${CMAKE_MINIMUM_VERSION}) project(Maths) +kasper_module_paths(Kommon) + # dependencies -find_package(Boost 1.58 REQUIRED) +find_package(Boost ${BOOST_MINIMUM_VERSION} REQUIRED) # headers set(HEADER_PATH - ${CMAKE_CURRENT_SOURCE_DIR}/include/ + ${CMAKE_CURRENT_SOURCE_DIR}/include/ ) # sources @@ -16,29 +18,20 @@ set(SOURCE_BASENAMES ) foreach(BASENAME ${SOURCE_BASENAMES}) - list(APPEND SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/${BASENAME}) + list(APPEND SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/${BASENAME}) endforeach(BASENAME) # library -add_library(${PROJECT_NAME} SHARED ${SOURCES}) -target_include_directories(${PROJECT_NAME} - PUBLIC $ $ - PRIVATE ${Boost_INCLUDE_DIRS} +add_library(Maths SHARED ${SOURCES}) +target_include_directories(Maths + PUBLIC $ $ ) -target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14) -target_link_libraries(${PROJECT_NAME}) - -# install headers and lib -#include(GNUInstallDirs) -install(DIRECTORY ${HEADER_PATH} DESTINATION ${INCLUDE_INSTALL_DIR}) -install(TARGETS ${PROJECT_NAME} - EXPORT ${PROJECT_NAME}Targets - DESTINATION ${LIB_INSTALL_DIR} +target_compile_features(Maths PRIVATE cxx_std_14) +target_link_libraries(Maths + PRIVATE + Boost::boost ) -# install CMake Targets and Config -install(EXPORT ${PROJECT_NAME}Targets - NAMESPACE ${PROJECT_NAME}:: - DESTINATION ${CMAKE_INSTALL_DIR}/${PROJECT_NAME} -) -install(FILES ${PROJECT_NAME}Config.cmake DESTINATION ${CMAKE_INSTALL_DIR}/${PROJECT_NAME}) +kasper_install_libraries(Maths) + +kasper_install_module() diff --git a/Kommon/Core/Maths/MathsConfig.cmake b/Kommon/Core/Maths/MathsConfig.cmake.in similarity index 100% rename from Kommon/Core/Maths/MathsConfig.cmake rename to Kommon/Core/Maths/MathsConfig.cmake.in diff --git a/Kommon/Core/Maths/MathsConfigVersion.cmake.in b/Kommon/Core/Maths/MathsConfigVersion.cmake.in new file mode 100644 index 000000000..25f052f29 --- /dev/null +++ b/Kommon/Core/Maths/MathsConfigVersion.cmake.in @@ -0,0 +1,11 @@ +set(PACKAGE_VERSION "@MODULE_VERSION@") + +# Check whether the requested PACKAGE_FIND_VERSION is compatible +if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() diff --git a/Kommon/Core/Utility/KMathIntegrator.h b/Kommon/Core/Utility/KMathIntegrator.h index 2a526bebb..9ab2699c2 100644 --- a/Kommon/Core/Utility/KMathIntegrator.h +++ b/Kommon/Core/Utility/KMathIntegrator.h @@ -12,11 +12,38 @@ #include "KMathKahanSum.h" #include +#include #include #include #include #include +#ifdef KASPER_USE_GSL +#include +#include "KGslErrorHandler.h" + +namespace { + +//inspired by fitrium - thx! +using FType = const std::function; +/** + * Create a gsl_function from c++ template function + * + * @param integrand The c++ style function object + * @returns A gsl_function usable by the GSL integration functions + */ +inline gsl_function GSLFunction(FType& integrand) +{ + gsl_function gsl_func; + gsl_func.function = [](double x, void* param) { return (*static_cast(param))(x); }; + gsl_func.params = (void*)&integrand; + return gsl_func; + +} +} +#endif /* KASPER_USE_GSL */ + + namespace katrin { @@ -29,7 +56,8 @@ enum class KEMathIntegrationMethod Simpson, K3, K4, - Romberg + Romberg, + QAGS }; // forward declarations @@ -156,6 +184,10 @@ class KMathIntegrator : private XSamplingPolicy template XFloatT QTrap(XIntegrandType&& integrand); template XFloatT QSimp(XIntegrandType&& integrand); template XFloatT QRomb(XIntegrandType&& integrand, const uint32_t K = 5); +#ifdef KASPER_USE_GSL + template XFloatT QAGIU(XIntegrandType&& integrand); + template XFloatT QAGS(XIntegrandType&& integrand); +#endif XFloatT fXStart; XFloatT fXEnd; @@ -316,6 +348,13 @@ inline XFloatT KMathIntegrator::Integrate(XIntegrandTy if (fJMax < fJMin) fJMax = fJMin; + if ((std::isinf(fXEnd) and fXEnd>0)) +#ifdef KASPER_USE_GSL + return QAGIU(std::forward(integrand)); +#else + throw KMathIntegratorException() << "Cannot integrate up to infinity without GSL libraries."; +#endif + switch (fMethod) { case KEMathIntegrationMethod::Trapezoidal: return QTrap(std::forward(integrand)); @@ -327,6 +366,12 @@ inline XFloatT KMathIntegrator::Integrate(XIntegrandTy return QRomb(std::forward(integrand), 4); case KEMathIntegrationMethod::Romberg: return QRomb(std::forward(integrand), 5); + case KEMathIntegrationMethod::QAGS: +#ifdef KASPER_USE_GSL + return QAGS(std::forward(integrand)); +#else + throw KMathIntegratorException() << "Cannot use QAGS/GSL in build without GSL libraries."; +#endif default: throw KMathIntegratorException() << "Invalid integration method specified."; } @@ -461,6 +506,87 @@ inline XFloatT KMathIntegrator::QRomb(XIntegrandType&& } } +#ifdef KASPER_USE_GSL +template +template +inline XFloatT KMathIntegrator::QAGS(XIntegrandType&& integrand) +{ + /*Use gsl implementation for integral int_a^b. Implementation is experimental. */ + const uint ws_size = 100; + gsl_integration_workspace* workspace = gsl_integration_workspace_alloc(ws_size); + FType proxy = integrand; + gsl_function F=GSLFunction(proxy); + + XFloatT AbsError; + + try { + gsl_integration_qags(&F,fXStart,fXEnd,0,fPrecision,ws_size,workspace,&fCurrentResult,&AbsError); + } + catch (KGslException &e) { + if (fThrowExceptions) + throw KMathIntegratorException() << "Error encountered in routine QAGS: " << e.what(); + } + +// KGslErrorHandler::GetInstance().Reset(); + + fIteration+=ilog2_ceil(workspace->size); //crude approximation, since QAGS log2(workspace->size) is non integer + gsl_integration_workspace_free(workspace); + + if (fabs(AbsError/fCurrentResult)(integrand), 5); + } + else + return fCurrentResult; + } + else { + if (fThrowExceptions) + throw KMathIntegratorException() << "Non finite result in routine QAGS."; + + Reset(); + return QRomb(std::forward(integrand), 5); + } +} + +template +template +inline XFloatT KMathIntegrator::QAGIU(XIntegrandType&& integrand) +{ + /*Use gsl implementation for integral int_xmin^infty. Use case is the krypton spectrum. Implementation is experimental. */ + const uint ws_size = 100; + gsl_integration_workspace* workspace = gsl_integration_workspace_alloc(ws_size); + FType proxy = integrand; + gsl_function F=GSLFunction(proxy); + + double Precision = fPrecision<1E-5 ? 1E-5 : fPrecision; + // QAGIU is only used far above the last krypton line with very small rate. Too large precision does not work here. + + XFloatT AbsError; + + try { + gsl_integration_qagiu(&F,fXStart,0,Precision,ws_size,workspace,&fCurrentResult,&AbsError); + } + catch (KGslException &e) { + if (fThrowExceptions) + throw KMathIntegratorException() << "Error encountered in routine QAGIU: " << e.what(); + } + +// KGslErrorHandler::GetInstance().Reset(); + + fIteration+=ilog2_ceil(workspace->size); //crude approximation, since QAGIU log2(workspace->size) is non integer + gsl_integration_workspace_free(workspace); + + if (std::isnormal(fCurrentResult)) + return fCurrentResult; + else + throw KMathIntegratorException() << "Non finite result in routine QAGIU."; +} +#endif /* KASPER_USE_GSL */ + template inline XFloatT KMathIntegrator::K1DPolyInterpolator::RawInterpolate(int32_t jl, XFloatT x) { diff --git a/Kommon/Core/Utility/KMathKahanSum.h b/Kommon/Core/Utility/KMathKahanSum.h index 2e96c7993..fa75e1bff 100644 --- a/Kommon/Core/Utility/KMathKahanSum.h +++ b/Kommon/Core/Utility/KMathKahanSum.h @@ -26,25 +26,33 @@ template class KMathKahanSum virtual ~KMathKahanSum() = default; KMathKahanSum& Add(FloatT summand); - KMathKahanSum& Subtract(FloatT summand) + inline KMathKahanSum& Subtract(FloatT summand) { return Add(-summand); } - FloatT Result() const + inline FloatT Result() const { return fSum; } + inline FloatT Sum() const + { + return fSum; + } + inline FloatT Compensation() const + { + return fCompensation; + } - KMathKahanSum& operator+=(FloatT summand) + inline KMathKahanSum& operator+=(FloatT summand) { return Add(summand); } - KMathKahanSum& operator-=(FloatT summand) + inline KMathKahanSum& operator-=(FloatT summand) { return Subtract(summand); } // KMathKahanSum& operator() (FloatT summand) { return Add(summand); } - operator FloatT() const + inline operator FloatT() const { return Result(); } diff --git a/Kommon/Core/Utility/KMessage.cxx b/Kommon/Core/Utility/KMessage.cxx index 15d111826..efbada3b7 100644 --- a/Kommon/Core/Utility/KMessage.cxx +++ b/Kommon/Core/Utility/KMessage.cxx @@ -148,7 +148,9 @@ void KMessage::EndLine(const KMessageLineEnd& aLineEnd) void KMessage::Flush() { - if ((fSeverity <= fTerminalVerbosity) && (fTerminalStream != nullptr) && (fTerminalStream->good() == true)) { + KMessageSeverity displayedSeverity = KMessageTable::GetInstance().CorrectedLevel(fSeverity); + + if ((displayedSeverity <= fTerminalVerbosity) && (fTerminalStream != nullptr) && (fTerminalStream->good() == true)) { for (auto& It : fMessageLines) { (*fTerminalStream) << Prefix() << (It == fMessageLines.front() ? "" : TabIndent) << It.first << Suffix() << It.second; @@ -301,6 +303,7 @@ std::ostream* KMessage::GetLogStream() return fLogStream; } + } // namespace katrin namespace katrin @@ -313,7 +316,8 @@ KMessageTable::KMessageTable() : fTerminalVerbosity(eNormal), fTerminalStream(&cerr), fLogVerbosity(eInfo), - fLogStream(nullptr) + fLogStream(nullptr), + fVerbosityLevel(0) {} KMessageTable::~KMessageTable() = default; @@ -461,4 +465,19 @@ ostream* KMessageTable::GetLogStream() return fLogStream; } +void KMessageTable::SetVerbosityLevel(int level) +{ + fVerbosityLevel = level; +} +KMessageSeverity KMessageTable::CorrectedLevel(const KMessageSeverity& level) const +{ + // smaller value means higher message severity + auto result = static_cast(level - fVerbosityLevel); + if (result <= KMessageSeverity::eErrorMessage) + return KMessageSeverity::eErrorMessage; + else if (result >= KMessageSeverity::eDebugMessage) + return KMessageSeverity::eDebugMessage; + return result; +} + } // namespace katrin diff --git a/Kommon/Core/Utility/KMessage.h b/Kommon/Core/Utility/KMessage.h index 33b37d71b..ed20659e0 100644 --- a/Kommon/Core/Utility/KMessage.h +++ b/Kommon/Core/Utility/KMessage.h @@ -266,6 +266,9 @@ class KMessageTable : public KSingleton void SetLogStream(std::ostream* aLogStream); std::ostream* GetLogStream(); + void SetVerbosityLevel(int level = 0); + KMessageSeverity CorrectedLevel(const KMessageSeverity& level) const; + private: using MessageMap = std::map; using MessageEntry = MessageMap::value_type; @@ -282,6 +285,7 @@ class KMessageTable : public KSingleton std::ostream* fTerminalStream; KMessageSeverity fLogVerbosity; std::ostream* fLogStream; + int fVerbosityLevel; }; } // namespace katrin diff --git a/Kommon/Core/Utility/KUtilityMessage.cxx b/Kommon/Core/Utility/KUtilityMessage.cxx index b4e723866..8182d3102 100644 --- a/Kommon/Core/Utility/KUtilityMessage.cxx +++ b/Kommon/Core/Utility/KUtilityMessage.cxx @@ -1,3 +1,3 @@ #include "KUtilityMessage.h" -KMESSAGE_DEFINE(katrin, utilmsg, KUtility, KUTILITY) +KMESSAGE_DEFINE(katrin, utilmsg, k_utility, KUTILITY) diff --git a/Kommon/Gsl/CMakeLists.txt b/Kommon/Gsl/CMakeLists.txt index 4748f1f4a..56793299d 100644 --- a/Kommon/Gsl/CMakeLists.txt +++ b/Kommon/Gsl/CMakeLists.txt @@ -1,8 +1,3 @@ -# internal -kasper_internal_include_directories( - Utility -) - # headers set(KOMMON_GSL_HEADER_FILES Utility/KMathPolynomialSolver.h @@ -17,7 +12,6 @@ set( KOMMON_GSL_SOURCE_FILES Utility/KGslErrorHandler.cxx ) - # propagate path variable to parent scope kasper_append_paths( KOMMON_HEADER_FILES ${KOMMON_GSL_HEADER_FILES} ) kasper_append_paths( KOMMON_SOURCE_FILES ${KOMMON_GSL_SOURCE_FILES} ) diff --git a/Kommon/KommonConfig.cmake.in b/Kommon/KommonConfig.cmake.in new file mode 100644 index 000000000..1a0c8fa9d --- /dev/null +++ b/Kommon/KommonConfig.cmake.in @@ -0,0 +1,30 @@ +include(CMakeFindDependencyMacro) + +set(KASPER_USE_BOOST @KASPER_USE_BOOST@) +if(KASPER_USE_BOOST) + find_dependency( Boost @BOOST_MINIMUM_VERSION@ COMPONENTS filesystem system ) +endif(KASPER_USE_BOOST) + +set(KASPER_USE_ROOT @KASPER_USE_ROOT@) +if(KASPER_USE_ROOT) + find_dependency( ROOT @ROOT_MINIMUM_VERSION@ CONFIG ) +endif(KASPER_USE_ROOT) + +set(KASPER_USE_GSL @KASPER_USE_GSL@) +if(KASPER_USE_GSL) + find_dependency( GSL ) +endif(KASPER_USE_GSL) + +set(KASPER_USE_TBB @KASPER_USE_TBB@) +if(KASPER_USE_TBB) + find_dependency( TBB ) +endif(KASPER_USE_TBB) + +set(KASPER_USE_VTK @KASPER_USE_VTK@) +if(KASPER_USE_VTK) + find_dependency( VTK NO_MODULE ) +endif(KASPER_USE_VTK) + +if(NOT TARGET @PROJECT_NAME@::@PROJECT_NAME@) + include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +endif() diff --git a/Kommon/KommonConfigVersion.cmake.in b/Kommon/KommonConfigVersion.cmake.in new file mode 100644 index 000000000..25f052f29 --- /dev/null +++ b/Kommon/KommonConfigVersion.cmake.in @@ -0,0 +1,11 @@ +set(PACKAGE_VERSION "@MODULE_VERSION@") + +# Check whether the requested PACKAGE_FIND_VERSION is compatible +if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() diff --git a/Kommon/ModuleConfig.cmake.in b/Kommon/ModuleConfig.cmake.in deleted file mode 100644 index 74855f886..000000000 --- a/Kommon/ModuleConfig.cmake.in +++ /dev/null @@ -1,25 +0,0 @@ -if(@PROJECT_NAME@_FOUND) - return() -endif() - -set(@PROJECT_NAME@_FOUND TRUE) - -# Update this section - -# The extra libraries one has to link against -set(@PROJECT_NAME@_DEPENDS @ROOT_LIBRARIES@ @Boost_LIBRARIES@ @GSL_LIBRARIES@ @VTK_LIBRARIES@) -# End - -set(@PROJECT_NAME@_VERSION_MAJOR @MODULE_VERSION_MAJOR@) -set(@PROJECT_NAME@_VERSION_MINOR @MODULE_VERSION_MINOR@) -set(@PROJECT_NAME@_VERSION_PATCH @MODULE_VERSION_PATCH@) -set(@PROJECT_NAME@_VERSION @MODULE_VERSION@) - -set(@PROJECT_NAME@_INCLUDE_DIRS @MODULE_INCLUDE_DIRS@) - -set(@PROJECT_NAME@_LIBRARIES Kommon) -if( KASPER_USE_VTK ) - set(@PROJECT_NAME@_Vtk_LIBRARIES KommonVtk) -endif() - -mark_as_advanced(@PROJECT_NAME@_DIR) diff --git a/Kommon/ModuleConfigInstalled.cmake.in b/Kommon/ModuleConfigInstalled.cmake.in deleted file mode 100644 index c57d4a1aa..000000000 --- a/Kommon/ModuleConfigInstalled.cmake.in +++ /dev/null @@ -1,29 +0,0 @@ -if(@PROJECT_NAME@_FOUND) - return() -endif() - -set(@PROJECT_NAME@_FOUND TRUE) - -# Update this section -set(@PROJECT_NAME@_DEPENDS @ROOT_LIBRARIES@ @Boost_LIBRARIES@ @GSL_LIBRARIES@) -# End - -set(@PROJECT_NAME@_VERSION_MAJOR @MODULE_VERSION_MAJOR@) -set(@PROJECT_NAME@_VERSION_MINOR @MODULE_VERSION_MINOR@) -set(@PROJECT_NAME@_VERSION_PATCH @MODULE_VERSION_PATCH@) -set(@PROJECT_NAME@_VERSION @MODULE_VERSION@) - -get_filename_component(MODULE_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) -if(EXISTS "${MODULE_CMAKE_DIR}/ModuleTargets.cmake") - include("${MODULE_CMAKE_DIR}/ModuleTargets.cmake") -elseif(NOT KASPER_TARGETS_INCLUDED) - include("${MODULE_CMAKE_DIR}/../Kasper/KasperTargets.cmake") - set(KASPER_TARGETS_INCLUDED TRUE) -endif() - -set(@PROJECT_NAME@_INCLUDE_DIRS @INSTALLED_INCLUDE_DIRS@) - -set(@PROJECT_NAME@_LIBRARIES Kommon) -if( KASPER_USE_VTK ) - set(@PROJECT_NAME@_Vtk_LIBRARIES KommonVtk) -endif() diff --git a/Kommon/Root/CMakeLists.txt b/Kommon/Root/CMakeLists.txt index b8a36e5f9..dd16961f0 100644 --- a/Kommon/Root/CMakeLists.txt +++ b/Kommon/Root/CMakeLists.txt @@ -1,10 +1,3 @@ -# internal -kasper_internal_include_directories( - File - Initialization - Utility -) - # headers set(KOMMON_ROOT_HEADER_FILES File/KRootFile.h diff --git a/Kommon/Root/Initialization/KFormulaProcessor.cc b/Kommon/Root/Initialization/KFormulaProcessor.cc index 3a9d591a6..e203c6e2a 100644 --- a/Kommon/Root/Initialization/KFormulaProcessor.cc +++ b/Kommon/Root/Initialization/KFormulaProcessor.cc @@ -34,7 +34,7 @@ bool KFormulaProcessor::EvaluateTinyExpression(const std::string& tExpr, double& // replace some ROOT::TMath functions by STL equivalents const vector> tStandardFunctions = { - // standard functions + // C standard functions {"TMath::Abs", "fabs"}, {"TMath::ACos", "acos"}, {"TMath::ASin", "asin"}, @@ -52,6 +52,10 @@ bool KFormulaProcessor::EvaluateTinyExpression(const std::string& tExpr, double& {"TMath::SinH", "sinh"}, {"TMath::Tan", "tan"}, {"TMath::TanH", "tanh"}, + // additional functions (provided by TinyExpr) + {"TMath::Factorial", "fac"}, + {"TMath::Binomial", "ncr"}, + {"TMath::Binomial", "npr"}, // additional constants (provided by TinyExpr) {"TMath::Pi()", "pi"}, {"TMath::E()", "e"}, diff --git a/Kommon/Root/Utility/KROOTWindow.cxx b/Kommon/Root/Utility/KROOTWindow.cxx index d24775203..69054e04b 100644 --- a/Kommon/Root/Utility/KROOTWindow.cxx +++ b/Kommon/Root/Utility/KROOTWindow.cxx @@ -3,6 +3,7 @@ #include "KROOTPad.h" #include "KROOTPainter.h" #include "KUtilityMessage.h" +#include "KXMLInitializer.hh" #ifdef KASPER_USE_BOOST //#include "KPathUtils.h" @@ -39,7 +40,7 @@ KROOTWindow::~KROOTWindow() void KROOTWindow::Render() { - utilmsg(eNormal) << "KROOTWindow starts to render!" << eom; + utilmsg(eInfo) << "KROOTWindow starts to render!" << eom; // gStyle->SetPadBottomMargin(0.1); // gStyle->SetPadRightMargin(0.1); @@ -49,15 +50,18 @@ void KROOTWindow::Render() gStyle->SetTitleAlign(23); gStyle->SetTitleSize(0.08, "t"); - if (gApplication) { - fApplication = gApplication; - } - else { - fApplication = new TApplication("My ROOT Application", nullptr, nullptr); - } + if (!KXMLInitializer::GetInstance().IsBatchMode()) + { + if (gApplication) { + fApplication = gApplication; + } + else { + fApplication = new TApplication("My ROOT Application", nullptr, nullptr); + } - TQObject::Connect("TCanvas", "Closed()", "TApplication", fApplication, "Terminate()"); - TQObject::Connect("TPad", "Closed()", "TApplication", fApplication, "Terminate()"); + TQObject::Connect("TCanvas", "Closed()", "TApplication", fApplication, "Terminate()"); + TQObject::Connect("TPad", "Closed()", "TApplication", fApplication, "Terminate()"); + } fCanvas = new TCanvas(GetName().c_str(), GetName().c_str(), 10, 10, fCanvasWidth, fCanvasHeight); @@ -129,14 +133,20 @@ void KROOTWindow::Render() (*tPadIt)->Render(); } - utilmsg(eNormal) << "KROOTWindow finished to render!" << eom; + utilmsg(eInfo) << "KROOTWindow finished to render!" << eom; return; } void KROOTWindow::Display() { - utilmsg(eNormal) << "KROOTWindow starts to display!" << eom; + if (KXMLInitializer::GetInstance().IsBatchMode()) { + utilmsg(eWarning) << "KROOTWindow display disabled in batch mode" + << eom; + return; + } + + utilmsg(eInfo) << "KROOTWindow starts to display!" << eom; fCanvas->cd(); if (fFrame) { @@ -156,13 +166,13 @@ void KROOTWindow::Display() (*tPadIt)->Display(); } - utilmsg(eNormal) << "KROOTWindow finished to display!" << eom; + utilmsg(eInfo) << "KROOTWindow finished to display!" << eom; return; } void KROOTWindow::Write() { - utilmsg(eNormal) << "KROOTWindow starts to write!" << eom; + utilmsg(eInfo) << "KROOTWindow starts to write!" << eom; if (fWriteEnabled) { string tOutputStringRoot; @@ -195,14 +205,14 @@ void KROOTWindow::Write() (*tPadIt)->Write(); } - if (fActive) { + if (fActive && fApplication) { if (!fApplication->IsRunning()) { - utilmsg(eNormal) << "KROOTWindow starting the TApplication!" << eom; + utilmsg(eInfo) << "KROOTWindow starting the TApplication!" << eom; fApplication->Run(true); } } - utilmsg(eNormal) << "KROOTWindow finished to write!" << eom; + utilmsg(eInfo) << "KROOTWindow finished to write!" << eom; return; } diff --git a/Kommon/TBB/CMakeLists.txt b/Kommon/TBB/CMakeLists.txt index f7b984f20..08ab25132 100644 --- a/Kommon/TBB/CMakeLists.txt +++ b/Kommon/TBB/CMakeLists.txt @@ -1,8 +1,6 @@ -kasper_internal_include_directories( Utility ) - # headers set( KOMMON_TBB_HEADER_FILENAMES - Utility/KMathIntegratorThreaded.h + Utility/KMathIntegratorThreaded.h ) # source @@ -12,4 +10,4 @@ set( KOMMON_TBB_HEADER_FILENAMES # propagate path variable to parent scope kasper_append_paths( KOMMON_HEADER_FILES ${KOMMON_TBB_HEADER_FILENAMES} ) -#kasper_append_paths( KOMMON_SOURCE_FILES ${KOMMON_TBB_SOURCE_FILENAMES} ) \ No newline at end of file +#kasper_append_paths( KOMMON_SOURCE_FILES ${KOMMON_TBB_SOURCE_FILENAMES} ) diff --git a/Kommon/Vtk/CMakeLists.txt b/Kommon/Vtk/CMakeLists.txt index fe2769d84..910535ad8 100644 --- a/Kommon/Vtk/CMakeLists.txt +++ b/Kommon/Vtk/CMakeLists.txt @@ -1,10 +1,4 @@ -kasper_find_vtk() -if( VTK_MAJOR_VERSION GREATER 5 ) - add_definitions(-DVTK6) -endif() - -# internal -kasper_internal_include_directories( Utility ) +find_package(VTK CONFIG REQUIRED) # headers set( KOMMON_VTK_HEADER_FILENAMES @@ -20,10 +14,52 @@ set( KOMMON_VTK_SOURCE_FILENAMES Utility/KVTKWindowBuilder.cxx ) -# propagate path variable to parent scope -kasper_install_headers( ${KOMMON_VTK_HEADER_FILENAMES} ) +add_library( KommonVtk SHARED + ${KOMMON_VTK_SOURCE_FILENAMES} ${KOMMON_VTK_HEADER_FILENAMES}) -add_library( KommonVtk SHARED ${KOMMON_VTK_SOURCE_FILENAMES} ) -target_link_libraries( KommonVtk ${VTK_LIBRARIES} Kommon ) -kasper_install_libraries( KommonVtk ) +# get header paths from collected header files +foreach(HEADER ${KOMMON_VTK_HEADER_FILENAMES}) + get_filename_component(DIRNAME ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER} DIRECTORY) + target_include_directories(KommonVtk PUBLIC $) +endforeach(HEADER) +target_include_directories(KommonVtk PUBLIC $) + +# VTK should *really* use proper CMake targets at this point :-/ +# The lines below are adapted from the `UseVTK.cmake` file, located at ${VTK_USE_FILE} + +# Add compiler flags needed to use VTK. +separate_arguments(_VTK_REQUIRED_CXX_FLAGS UNIX_COMMAND "${VTK_REQUIRED_CXX_FLAGS}") +target_compile_options(KommonVtk PUBLIC ${_VTK_REQUIRED_CXX_FLAGS}) +set(_target_type "$") +add_link_options( $<$:${VTK_REQUIRED_EXE_LINKER_FLAGS}> ) +add_link_options( $<$:${VTK_REQUIRED_SHARED_LINKER_FLAGS}> ) +add_link_options( $<$:${VTK_REQUIRED_MODULE_LINKER_FLAGS}> ) + +# Add preprocessor definitions needed to use VTK. +set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS ${VTK_DEFINITIONS}) + +# Add include directories needed to use VTK. +target_include_directories(KommonVtk PUBLIC ${VTK_INCLUDE_DIRS}) + +# Add link directories needed to use VTK. +target_link_directories(KommonVtk PUBLIC ${VTK_LIBRARY_DIRS}) +target_compile_definitions(KommonVtk PUBLIC KASPER_USE_VTK) +target_link_libraries( KommonVtk + PUBLIC + Kommon + ${VTK_LIBRARIES} +) + +if( VTK_MAJOR_VERSION GREATER 6 ) + if( CMAKE_CXX_COMPILER_ID STREQUAL "Clang" ) + target_compile_options(KommonVtk PUBLIC -Wno-inconsistent-missing-override) # FIXME: vtk doesn't care about warnings, it seems + endif() +endif() + +if( VTK_MAJOR_VERSION GREATER 5 ) + target_compile_definitions(KommonVtk PRIVATE VTK6) +endif() + +kasper_install_libraries( KommonVtk ) +kasper_install_headers( ${KOMMON_VTK_HEADER_FILENAMES} ) diff --git a/Kommon/Vtk/Utility/KVTKPainter.cxx b/Kommon/Vtk/Utility/KVTKPainter.cxx index c4379d88e..eafdeb5ce 100644 --- a/Kommon/Vtk/Utility/KVTKPainter.cxx +++ b/Kommon/Vtk/Utility/KVTKPainter.cxx @@ -54,4 +54,14 @@ void KVTKPainter::SetWriteMode(bool aMode) return; } +std::string KVTKPainter::HelpText() +{ + return ""; +} + +void KVTKPainter::OnKeyPress(vtkObject* /*caller*/, long unsigned int /*eventId*/, void* /*client*/, void* /*callData*/) +{ + return; +} + } // namespace katrin diff --git a/Kommon/Vtk/Utility/KVTKPainter.h b/Kommon/Vtk/Utility/KVTKPainter.h index 0304f848f..72201043d 100644 --- a/Kommon/Vtk/Utility/KVTKPainter.h +++ b/Kommon/Vtk/Utility/KVTKPainter.h @@ -3,6 +3,8 @@ #include "KPainter.h" +#include + namespace katrin { class KVTKWindow; @@ -20,6 +22,9 @@ class KVTKPainter : public KPainter void SetDisplayMode(bool aMode); void SetWriteMode(bool aMode); + virtual std::string HelpText(); + virtual void OnKeyPress(vtkObject* /*caller*/, long unsigned int /*eventId*/, void* /*client*/, void* /*callData*/); + protected: KVTKWindow* fWindow; bool fDisplayEnabled; diff --git a/Kommon/Vtk/Utility/KVTKWindow.cxx b/Kommon/Vtk/Utility/KVTKWindow.cxx index 4c418950e..8ea37c3fb 100644 --- a/Kommon/Vtk/Utility/KVTKWindow.cxx +++ b/Kommon/Vtk/Utility/KVTKWindow.cxx @@ -3,6 +3,7 @@ #include "KFile.h" #include "KUtilityMessage.h" #include "KVTKPainter.h" +#include "KXMLInitializer.hh" #include "vtkAnnotatedCubeActor.h" #include "vtkAppendPolyData.h" #include "vtkAxesActor.h" @@ -23,6 +24,7 @@ #include "vtkPolyDataMapper2D.h" #include "vtkPropCollection.h" #include "vtkProperty.h" +#include "vtkProperty2D.h" #include "vtkQuad.h" #include "vtkSmartPointer.h" #include "vtkTIFFWriter.h" @@ -63,13 +65,15 @@ KVTKWindow::~KVTKWindow() void KVTKWindow::Render() { + utilmsg(eInfo) << "KVTKWindow starts to render!" << eom; + /* setup writer */ if (fWriteToggle == true) { fWriter = vtkSmartPointer::New(); } /* setup display */ - if (fDisplayToggle == true) { + if (fDisplayToggle == true && !KXMLInitializer::GetInstance().IsBatchMode()) { double textColor[] = {// NOLINT fFrameRed < .5 ? 1. : 0, fFrameGreen < .5 ? 1. : 0, @@ -185,49 +189,62 @@ void KVTKWindow::Render() (*tIt)->Render(); } + utilmsg(eInfo) << "KVTKWindow finished to render!" << eom; return; } void KVTKWindow::Display() { - PainterIt tIt; - if (fDisplayToggle == true) { - /* display painters */ - for (tIt = fPainters.begin(); tIt != fPainters.end(); tIt++) { - (*tIt)->Display(); - } + if (KXMLInitializer::GetInstance().IsBatchMode()) { + utilmsg(eWarning) << "KVTKWindow display disabled in batch mode" + << eom; + return; + } - /* add help actor if necessary */ - if (fHelpToggle == true) { - fRenderer->AddActor(fHelpActor); - } + if (! fDisplayToggle) + return; - /* add data actor if necessary */ - if (fDataToggle == true) { - fRenderer->AddActor(fDataActor); - } + utilmsg(eInfo) << "KVTKWindow starts to display!" << eom; - /* add axis actor if necessary */ - if (fAxisToggle == true) { - fOrientationWidget->EnabledOn(); - } + PainterIt tIt; + /* display painters */ + for (tIt = fPainters.begin(); tIt != fPainters.end(); tIt++) { + (*tIt)->Display(); + } - /* enable parallel projection if necessary */ - if (fParallelProjectionToggle == true) { - fRenderer->GetActiveCamera()->SetParallelProjection(1); - } + /* add help actor if necessary */ + if (fHelpToggle == true) { + fRenderer->AddActor(fHelpActor); + } - /* setup renderer */ - fRenderer->ResetCamera(); - fRenderWindow->Render(); - fRenderInteractor->Start(); + /* add data actor if necessary */ + if (fDataToggle == true) { + fRenderer->AddActor(fDataActor); } + /* add axis actor if necessary */ + if (fAxisToggle == true) { + fOrientationWidget->EnabledOn(); + } + + /* enable parallel projection if necessary */ + if (fParallelProjectionToggle == true) { + fRenderer->GetActiveCamera()->SetParallelProjection(1); + } + + /* setup renderer */ + fRenderer->ResetCamera(); + fRenderWindow->Render(); + fRenderInteractor->Start(); + + utilmsg(eInfo) << "KVTKWindow finished to display!" << eom; return; } void KVTKWindow::Write() { + utilmsg(eInfo) << "KVTKWindow starts to write!" << eom; + PainterIt tIt; if (fWriteToggle == true) { /* write painters */ @@ -236,6 +253,7 @@ void KVTKWindow::Write() } } + utilmsg(eInfo) << "KVTKWindow finished to write!" << eom; return; } @@ -314,14 +332,24 @@ void KVTKWindow::UpdateHelp() tText << " pan - center button [3 button mouse], shift + left button [1 or 2 button mouse]" << '\n'; tText << " zoom - right button [3 button mouse], ctrl + shift + left button [1 or 2 button mouse]" << '\n'; tText << '\n'; - tText << "help toggle: h [" << (fHelpToggle ? "ON" : "OFF") << "]" << '\n'; - tText << "data toggle: d [" << (fDataToggle ? "ON" : "OFF") << "]" << '\n'; - tText << "axis toggle: a [" << (fAxisToggle ? "ON" : "OFF") << "]" << '\n'; - tText << "parallel projection toggle: p [" << (fParallelProjectionToggle ? "ON" : "OFF") << "]" << '\n'; - tText << '\n'; - tText << "take screenshot: s" << '\n'; - tText << "reset view: r" << '\n'; - tText << "quit: q" << '\n'; + tText << "key bindings:" << '\n'; + + for (auto & tPainter : fPainters) { + auto tVtkPainter = dynamic_cast(tPainter); + if (tVtkPainter) + tText << tVtkPainter->HelpText(); + } + + tText << " general:" << '\n'; + tText << " H - toggle help text [" << (fHelpToggle ? "ON" : "OFF") << "]" << '\n'; + tText << " D - toggle data display [" << (fDataToggle ? "ON" : "OFF") << "]" << '\n'; + tText << " A - toggle axis display [" << (fAxisToggle ? "ON" : "OFF") << "]" << '\n'; + tText << " P - toggle parallel projection [" << (fParallelProjectionToggle ? "ON" : "OFF") << "]" << '\n'; + tText << " W,S - switch wireframe / solid mode" << '\n'; + tText << " F12 - take screenshot" << '\n'; + tText << " F11 - toggle fullscreen" << '\n'; + tText << " F10 - reset view" << '\n'; + tText << " Q - quit" << '\n'; fHelpActor->SetText(2, tText.str().c_str()); @@ -381,23 +409,31 @@ void KVTKWindow::Screenshot() return; } -void KVTKWindow::OnKeyPress(vtkObject* aCaller, long unsigned int /*eventId*/, void* aClient, void* /*callData*/) +void KVTKWindow::OnKeyPress(vtkObject* aCaller, long unsigned int anEventId, void* aClient, void* aCallData) { auto* tWindow = static_cast(aClient); auto* tInteractor = static_cast(aCaller); + auto* tRenderWindow = tInteractor->GetRenderWindow(); string Symbol = tInteractor->GetKeySym(); bool WithShift = tInteractor->GetShiftKey(); bool WithCtrl = tInteractor->GetControlKey(); + utilmsg(eDebug) << "key press in VTK window: " << Symbol << (WithShift ? "+shift" : "") << (WithCtrl ? "+ctrl" : "") << eom; + if ((WithShift == false) && (WithCtrl == false)) { //screenshot - if (Symbol == string("s")) { + if (Symbol == string("F12")) { tWindow->Screenshot(); } + //fullscreen + if (Symbol == string("F11")) { + tRenderWindow->SetFullScreen(! tRenderWindow->GetFullScreen()); + } + //reset - else if (Symbol == string("r")) { + else if (Symbol == string("F10")) { tWindow->fRenderer->ResetCamera(); tWindow->fViewAngle = 45.; tWindow->fRenderer->GetActiveCamera()->SetViewAngle(tWindow->fViewAngle); @@ -452,6 +488,12 @@ void KVTKWindow::OnKeyPress(vtkObject* aCaller, long unsigned int /*eventId*/, v } } + for (auto & tPainter : tWindow->fPainters) { + auto tVtkPainter = dynamic_cast(tPainter); + if (tVtkPainter) + tVtkPainter->OnKeyPress(aCaller, anEventId, aClient, aCallData); + } + tWindow->UpdateHelp(); tWindow->UpdateData(); tWindow->fRenderWindow->Render(); diff --git a/Kommon/cmake/CMakeDependentOption.cmake b/Kommon/cmake/CMakeDependentOption.cmake index 21d3c96b3..6046d8585 100644 --- a/Kommon/cmake/CMakeDependentOption.cmake +++ b/Kommon/cmake/CMakeDependentOption.cmake @@ -1,27 +1,28 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -#.rst: -# CMakeDependentOption -# -------------------- -# -# Macro to provide an option dependent on other options. -# -# This macro presents an option to the user only if a set of other -# conditions are true. When the option is not presented a default value -# is used, but any value set by the user is preserved for when the -# option is presented again. Example invocation: -# -# :: -# -# CMAKE_DEPENDENT_OPTION(USE_FOO "Use Foo" ON -# "USE_BAR;NOT USE_ZOT" OFF) -# -# If USE_BAR is true and USE_ZOT is false, this provides an option -# called USE_FOO that defaults to ON. Otherwise, it sets USE_FOO to -# OFF. If the status of USE_BAR or USE_ZOT ever changes, any value for -# the USE_FOO option is saved so that when the option is re-enabled it -# retains its old value. +#[=======================================================================[.rst: +CMakeDependentOption +-------------------- + +Macro to provide an option dependent on other options. + +This macro presents an option to the user only if a set of other +conditions are true. When the option is not presented a default value +is used, but any value set by the user is preserved for when the +option is presented again. Example invocation: + +:: + + CMAKE_DEPENDENT_OPTION(USE_FOO "Use Foo" ON + "USE_BAR;NOT USE_ZOT" OFF) + +If USE_BAR is true and USE_ZOT is false, this provides an option +called USE_FOO that defaults to ON. Otherwise, it sets USE_FOO to +OFF. If the status of USE_BAR or USE_ZOT ever changes, any value for +the USE_FOO option is saved so that when the option is re-enabled it +retains its old value. +#]=======================================================================] macro(CMAKE_DEPENDENT_OPTION option doc default depends force) if(${option}_ISSET MATCHES "^${option}_ISSET$") diff --git a/Kommon/cmake/CMakeParseArguments.cmake b/Kommon/cmake/CMakeParseArguments.cmake new file mode 100644 index 000000000..c753b7f51 --- /dev/null +++ b/Kommon/cmake/CMakeParseArguments.cmake @@ -0,0 +1,12 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +CMakeParseArguments +------------------- + +This module once implemented the :command:`cmake_parse_arguments` command +that is now implemented natively by CMake. It is now an empty placeholder +for compatibility with projects that include it to get the command from +CMake 3.4 and lower. +#]=======================================================================] diff --git a/Kommon/cmake/CMakePushCheckState.cmake b/Kommon/cmake/CMakePushCheckState.cmake new file mode 100644 index 000000000..f6bfc120e --- /dev/null +++ b/Kommon/cmake/CMakePushCheckState.cmake @@ -0,0 +1,91 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +CMakePushCheckState +------------------- + + + +This module defines three macros: ``CMAKE_PUSH_CHECK_STATE()`` +``CMAKE_POP_CHECK_STATE()`` and ``CMAKE_RESET_CHECK_STATE()`` These macros can +be used to save, restore and reset (i.e., clear contents) the state of +the variables ``CMAKE_REQUIRED_FLAGS``, ``CMAKE_REQUIRED_DEFINITIONS``, +``CMAKE_REQUIRED_LINK_OPTIONS``, ``CMAKE_REQUIRED_LIBRARIES``, +``CMAKE_REQUIRED_INCLUDES`` and ``CMAKE_EXTRA_INCLUDE_FILES`` used by the +various Check-files coming with CMake, like e.g. ``check_function_exists()`` +etc. +The variable contents are pushed on a stack, pushing multiple times is +supported. This is useful e.g. when executing such tests in a Find-module, +where they have to be set, but after the Find-module has been executed they +should have the same value as they had before. + +``CMAKE_PUSH_CHECK_STATE()`` macro receives optional argument ``RESET``. +Whether it's specified, ``CMAKE_PUSH_CHECK_STATE()`` will set all +``CMAKE_REQUIRED_*`` variables to empty values, same as +``CMAKE_RESET_CHECK_STATE()`` call will do. + +Usage: + +.. code-block:: cmake + + cmake_push_check_state(RESET) + set(CMAKE_REQUIRED_DEFINITIONS -DSOME_MORE_DEF) + check_function_exists(...) + cmake_reset_check_state() + set(CMAKE_REQUIRED_DEFINITIONS -DANOTHER_DEF) + check_function_exists(...) + cmake_pop_check_state() +#]=======================================================================] + +macro(CMAKE_RESET_CHECK_STATE) + + set(CMAKE_EXTRA_INCLUDE_FILES) + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_DEFINITIONS) + set(CMAKE_REQUIRED_LINK_OPTIONS) + set(CMAKE_REQUIRED_LIBRARIES) + set(CMAKE_REQUIRED_FLAGS) + set(CMAKE_REQUIRED_QUIET) + +endmacro() + +macro(CMAKE_PUSH_CHECK_STATE) + + if(NOT DEFINED _CMAKE_PUSH_CHECK_STATE_COUNTER) + set(_CMAKE_PUSH_CHECK_STATE_COUNTER 0) + endif() + + math(EXPR _CMAKE_PUSH_CHECK_STATE_COUNTER "${_CMAKE_PUSH_CHECK_STATE_COUNTER}+1") + + set(_CMAKE_EXTRA_INCLUDE_FILES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_EXTRA_INCLUDE_FILES}) + set(_CMAKE_REQUIRED_INCLUDES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_INCLUDES}) + set(_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_DEFINITIONS}) + set(_CMAKE_REQUIRED_LINK_OPTIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_LINK_OPTIONS}) + set(_CMAKE_REQUIRED_LIBRARIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_LIBRARIES}) + set(_CMAKE_REQUIRED_FLAGS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_FLAGS}) + set(_CMAKE_REQUIRED_QUIET_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_QUIET}) + + if (${ARGC} GREATER 0 AND "${ARGV0}" STREQUAL "RESET") + cmake_reset_check_state() + endif() + +endmacro() + +macro(CMAKE_POP_CHECK_STATE) + +# don't pop more than we pushed + if("${_CMAKE_PUSH_CHECK_STATE_COUNTER}" GREATER "0") + + set(CMAKE_EXTRA_INCLUDE_FILES ${_CMAKE_EXTRA_INCLUDE_FILES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}}) + set(CMAKE_REQUIRED_INCLUDES ${_CMAKE_REQUIRED_INCLUDES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}}) + set(CMAKE_REQUIRED_DEFINITIONS ${_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}}) + set(CMAKE_REQUIRED_LINK_OPTIONS ${_CMAKE_REQUIRED_LINK_OPTIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}}) + set(CMAKE_REQUIRED_LIBRARIES ${_CMAKE_REQUIRED_LIBRARIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}}) + set(CMAKE_REQUIRED_FLAGS ${_CMAKE_REQUIRED_FLAGS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}}) + set(CMAKE_REQUIRED_QUIET ${_CMAKE_REQUIRED_QUIET_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}}) + + math(EXPR _CMAKE_PUSH_CHECK_STATE_COUNTER "${_CMAKE_PUSH_CHECK_STATE_COUNTER}-1") + endif() + +endmacro() diff --git a/Kommon/cmake/CheckForPthreads.c b/Kommon/cmake/CheckForPthreads.c new file mode 100644 index 000000000..e70ceb1da --- /dev/null +++ b/Kommon/cmake/CheckForPthreads.c @@ -0,0 +1,15 @@ +#include + +void* start_routine(void* args) +{ + return args; +} + +int main(void) +{ + /* This is a compile and link test, no code to actually run things. */ + pthread_t thread; + pthread_create(&thread, 0, start_routine, 0); + pthread_join(thread, 0); + return 0; +} diff --git a/Kommon/cmake/CheckSymbolExists.cmake b/Kommon/cmake/CheckSymbolExists.cmake new file mode 100644 index 000000000..b9ef8088f --- /dev/null +++ b/Kommon/cmake/CheckSymbolExists.cmake @@ -0,0 +1,134 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +CheckSymbolExists +----------------- + +Provides a macro to check if a symbol exists as a function, variable, +or macro in ``C``. + +.. command:: check_symbol_exists + + .. code-block:: cmake + + check_symbol_exists( ) + + Check that the ```` is available after including given header + ```` and store the result in a ````. Specify the list + of files in one argument as a semicolon-separated list. + ```` will be created as an internal cache variable. + +If the header files define the symbol as a macro it is considered +available and assumed to work. If the header files declare the symbol +as a function or variable then the symbol must also be available for +linking (so intrinsics may not be detected). +If the symbol is a type, enum value, or intrinsic it will not be recognized +(consider using :module:`CheckTypeSize` or :module:`CheckCSourceCompiles`). +If the check needs to be done in C++, consider using +:module:`CheckCXXSymbolExists` instead. + +The following variables may be set before calling this macro to modify +the way the check is run: + +``CMAKE_REQUIRED_FLAGS`` + string of compile command line flags. +``CMAKE_REQUIRED_DEFINITIONS`` + a :ref:`;-list ` of macros to define (-DFOO=bar). +``CMAKE_REQUIRED_INCLUDES`` + a :ref:`;-list ` of header search paths to pass to + the compiler. +``CMAKE_REQUIRED_LINK_OPTIONS`` + a :ref:`;-list ` of options to add to the link command. +``CMAKE_REQUIRED_LIBRARIES`` + a :ref:`;-list ` of libraries to add to the link + command. See policy :policy:`CMP0075`. +``CMAKE_REQUIRED_QUIET`` + execute quietly without messages. +#]=======================================================================] + +include_guard(GLOBAL) + +cmake_policy(PUSH) +cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced + +macro(CHECK_SYMBOL_EXISTS SYMBOL FILES VARIABLE) + if(CMAKE_C_COMPILER_LOADED) + __CHECK_SYMBOL_EXISTS_IMPL("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c" "${SYMBOL}" "${FILES}" "${VARIABLE}" ) + elseif(CMAKE_CXX_COMPILER_LOADED) + __CHECK_SYMBOL_EXISTS_IMPL("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.cxx" "${SYMBOL}" "${FILES}" "${VARIABLE}" ) + else() + message(FATAL_ERROR "CHECK_SYMBOL_EXISTS needs either C or CXX language enabled") + endif() +endmacro() + +macro(__CHECK_SYMBOL_EXISTS_IMPL SOURCEFILE SYMBOL FILES VARIABLE) + if(NOT DEFINED "${VARIABLE}" OR "x${${VARIABLE}}" STREQUAL "x${VARIABLE}") + set(CMAKE_CONFIGURABLE_FILE_CONTENT "/* */\n") + set(MACRO_CHECK_SYMBOL_EXISTS_FLAGS ${CMAKE_REQUIRED_FLAGS}) + if(CMAKE_REQUIRED_LINK_OPTIONS) + set(CHECK_SYMBOL_EXISTS_LINK_OPTIONS + LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS}) + else() + set(CHECK_SYMBOL_EXISTS_LINK_OPTIONS) + endif() + if(CMAKE_REQUIRED_LIBRARIES) + set(CHECK_SYMBOL_EXISTS_LIBS + LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) + else() + set(CHECK_SYMBOL_EXISTS_LIBS) + endif() + if(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_SYMBOL_EXISTS_INCLUDES + "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}") + else() + set(CMAKE_SYMBOL_EXISTS_INCLUDES) + endif() + foreach(FILE ${FILES}) + string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT + "#include <${FILE}>\n") + endforeach() + string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT + "\nint main(int argc, char** argv)\n{\n (void)argv;\n#ifndef ${SYMBOL}\n return ((int*)(&${SYMBOL}))[argc];\n#else\n (void)argc;\n return 0;\n#endif\n}\n") + + configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in" + "${SOURCEFILE}" @ONLY) + + if(NOT CMAKE_REQUIRED_QUIET) + message(STATUS "Looking for ${SYMBOL}") + endif() + try_compile(${VARIABLE} + ${CMAKE_BINARY_DIR} + "${SOURCEFILE}" + COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} + ${CHECK_SYMBOL_EXISTS_LINK_OPTIONS} + ${CHECK_SYMBOL_EXISTS_LIBS} + CMAKE_FLAGS + -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_SYMBOL_EXISTS_FLAGS} + "${CMAKE_SYMBOL_EXISTS_INCLUDES}" + OUTPUT_VARIABLE OUTPUT) + if(${VARIABLE}) + if(NOT CMAKE_REQUIRED_QUIET) + message(STATUS "Looking for ${SYMBOL} - found") + endif() + set(${VARIABLE} 1 CACHE INTERNAL "Have symbol ${SYMBOL}") + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Determining if the ${SYMBOL} " + "exist passed with the following output:\n" + "${OUTPUT}\nFile ${SOURCEFILE}:\n" + "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n") + else() + if(NOT CMAKE_REQUIRED_QUIET) + message(STATUS "Looking for ${SYMBOL} - not found") + endif() + set(${VARIABLE} "" CACHE INTERNAL "Have symbol ${SYMBOL}") + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Determining if the ${SYMBOL} " + "exist failed with the following output:\n" + "${OUTPUT}\nFile ${SOURCEFILE}:\n" + "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n") + endif() + endif() +endmacro() + +cmake_policy(POP) diff --git a/Kommon/cmake/FindBoost.cmake b/Kommon/cmake/FindBoost.cmake deleted file mode 100644 index 3e011adfb..000000000 --- a/Kommon/cmake/FindBoost.cmake +++ /dev/null @@ -1,2157 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#.rst: -# FindBoost -# --------- -# -# Find Boost include dirs and libraries -# -# Use this module by invoking find_package with the form:: -# -# find_package(Boost -# [version] [EXACT] # Minimum or EXACT version e.g. 1.67.0 -# [REQUIRED] # Fail with error if Boost is not found -# [COMPONENTS ...] # Boost libraries by their canonical name -# # e.g. "date_time" for "libboost_date_time" -# [OPTIONAL_COMPONENTS ...] -# # Optional Boost libraries by their canonical name) -# ) # e.g. "date_time" for "libboost_date_time" -# -# This module finds headers and requested component libraries OR a CMake -# package configuration file provided by a "Boost CMake" build. For the -# latter case skip to the "Boost CMake" section below. For the former -# case results are reported in variables:: -# -# Boost_FOUND - True if headers and requested libraries were found -# Boost_INCLUDE_DIRS - Boost include directories -# Boost_LIBRARY_DIRS - Link directories for Boost libraries -# Boost_LIBRARIES - Boost component libraries to be linked -# Boost__FOUND - True if component was found ( is upper-case) -# Boost__LIBRARY - Libraries to link for component (may include -# target_link_libraries debug/optimized keywords) -# Boost_VERSION - BOOST_VERSION value from boost/version.hpp -# Boost_LIB_VERSION - Version string appended to library filenames -# Boost_MAJOR_VERSION - Boost major version number (X in X.y.z) -# Boost_MINOR_VERSION - Boost minor version number (Y in x.Y.z) -# Boost_SUBMINOR_VERSION - Boost subminor version number (Z in x.y.Z) -# Boost_LIB_DIAGNOSTIC_DEFINITIONS (Windows) -# - Pass to add_definitions() to have diagnostic -# information about Boost's automatic linking -# displayed during compilation -# -# Note that Boost Python components require a Python version suffix -# (Boost 1.67 and later), e.g. ``python36`` or ``python27`` for the -# versions built against Python 3.6 and 2.7, respectively. This also -# applies to additional components using Python including -# ``mpi_python`` and ``numpy``. Earlier Boost releases may use -# distribution-specific suffixes such as ``2``, ``3`` or ``2.7``. -# These may also be used as suffixes, but note that they are not -# portable. -# -# This module reads hints about search locations from variables:: -# -# BOOST_ROOT - Preferred installation prefix -# (or BOOSTROOT) -# BOOST_INCLUDEDIR - Preferred include directory e.g. /include -# BOOST_LIBRARYDIR - Preferred library directory e.g. /lib -# Boost_NO_SYSTEM_PATHS - Set to ON to disable searching in locations not -# specified by these hint variables. Default is OFF. -# Boost_ADDITIONAL_VERSIONS -# - List of Boost versions not known to this module -# (Boost install locations may contain the version) -# -# and saves search results persistently in CMake cache entries:: -# -# Boost_INCLUDE_DIR - Directory containing Boost headers -# Boost_LIBRARY_DIR_RELEASE - Directory containing release Boost libraries -# Boost_LIBRARY_DIR_DEBUG - Directory containing debug Boost libraries -# Boost__LIBRARY_DEBUG - Component library debug variant -# Boost__LIBRARY_RELEASE - Component library release variant -# -# The following :prop_tgt:`IMPORTED` targets are also defined:: -# -# Boost::boost - Target for header-only dependencies -# (Boost include directory) -# Boost:: - Target for specific component dependency -# (shared or static library); is lower- -# case -# Boost::diagnostic_definitions - interface target to enable diagnostic -# information about Boost's automatic linking -# during compilation (adds BOOST_LIB_DIAGNOSTIC) -# Boost::disable_autolinking - interface target to disable automatic -# linking with MSVC (adds BOOST_ALL_NO_LIB) -# Boost::dynamic_linking - interface target to enable dynamic linking -# linking with MSVC (adds BOOST_ALL_DYN_LINK) -# -# Implicit dependencies such as Boost::filesystem requiring -# Boost::system will be automatically detected and satisfied, even -# if system is not specified when using find_package and if -# Boost::system is not added to target_link_libraries. If using -# Boost::thread, then Threads::Threads will also be added automatically. -# -# It is important to note that the imported targets behave differently -# than variables created by this module: multiple calls to -# find_package(Boost) in the same directory or sub-directories with -# different options (e.g. static or shared) will not override the -# values of the targets created by the first call. -# -# Users may set these hints or results as cache entries. Projects -# should not read these entries directly but instead use the above -# result variables. Note that some hint names start in upper-case -# "BOOST". One may specify these as environment variables if they are -# not specified as CMake variables or cache entries. -# -# This module first searches for the Boost header files using the above -# hint variables (excluding BOOST_LIBRARYDIR) and saves the result in -# Boost_INCLUDE_DIR. Then it searches for requested component libraries -# using the above hints (excluding BOOST_INCLUDEDIR and -# Boost_ADDITIONAL_VERSIONS), "lib" directories near Boost_INCLUDE_DIR, -# and the library name configuration settings below. It saves the -# library directories in Boost_LIBRARY_DIR_DEBUG and -# Boost_LIBRARY_DIR_RELEASE and individual library -# locations in Boost__LIBRARY_DEBUG and Boost__LIBRARY_RELEASE. -# When one changes settings used by previous searches in the same build -# tree (excluding environment variables) this module discards previous -# search results affected by the changes and searches again. -# -# Boost libraries come in many variants encoded in their file name. -# Users or projects may tell this module which variant to find by -# setting variables:: -# -# Boost_USE_DEBUG_LIBS - Set to ON or OFF to specify whether to search -# and use the debug libraries. Default is ON. -# Boost_USE_RELEASE_LIBS - Set to ON or OFF to specify whether to search -# and use the release libraries. Default is ON. -# Boost_USE_MULTITHREADED - Set to OFF to use the non-multithreaded -# libraries ('mt' tag). Default is ON. -# Boost_USE_STATIC_LIBS - Set to ON to force the use of the static -# libraries. Default is OFF. -# Boost_USE_STATIC_RUNTIME - Set to ON or OFF to specify whether to use -# libraries linked statically to the C++ runtime -# ('s' tag). Default is platform dependent. -# Boost_USE_DEBUG_RUNTIME - Set to ON or OFF to specify whether to use -# libraries linked to the MS debug C++ runtime -# ('g' tag). Default is ON. -# Boost_USE_DEBUG_PYTHON - Set to ON to use libraries compiled with a -# debug Python build ('y' tag). Default is OFF. -# Boost_USE_STLPORT - Set to ON to use libraries compiled with -# STLPort ('p' tag). Default is OFF. -# Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS -# - Set to ON to use libraries compiled with -# STLPort deprecated "native iostreams" -# ('n' tag). Default is OFF. -# Boost_COMPILER - Set to the compiler-specific library suffix -# (e.g. "-gcc43"). Default is auto-computed -# for the C++ compiler in use. A list may be -# used if multiple compatible suffixes should -# be tested for, in decreasing order of -# preference. -# Boost_ARCHITECTURE - Set to the architecture-specific library suffix -# (e.g. "-x64"). Default is auto-computed for the -# C++ compiler in use. -# Boost_THREADAPI - Suffix for "thread" component library name, -# such as "pthread" or "win32". Names with -# and without this suffix will both be tried. -# Boost_NAMESPACE - Alternate namespace used to build boost with -# e.g. if set to "myboost", will search for -# myboost_thread instead of boost_thread. -# -# Other variables one may set to control this module are:: -# -# Boost_DEBUG - Set to ON to enable debug output from FindBoost. -# Please enable this before filing any bug report. -# Boost_DETAILED_FAILURE_MSG -# - Set to ON to add detailed information to the -# failure message even when the REQUIRED option -# is not given to the find_package call. -# Boost_REALPATH - Set to ON to resolve symlinks for discovered -# libraries to assist with packaging. For example, -# the "system" component library may be resolved to -# "/usr/lib/libboost_system.so.1.67.0" instead of -# "/usr/lib/libboost_system.so". This does not -# affect linking and should not be enabled unless -# the user needs this information. -# Boost_LIBRARY_DIR - Default value for Boost_LIBRARY_DIR_RELEASE and -# Boost_LIBRARY_DIR_DEBUG. -# -# On Visual Studio and Borland compilers Boost headers request automatic -# linking to corresponding libraries. This requires matching libraries -# to be linked explicitly or available in the link library search path. -# In this case setting Boost_USE_STATIC_LIBS to OFF may not achieve -# dynamic linking. Boost automatic linking typically requests static -# libraries with a few exceptions (such as Boost.Python). Use:: -# -# add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS}) -# -# to ask Boost to report information about automatic linking requests. -# -# Example to find Boost headers only:: -# -# find_package(Boost 1.36.0) -# if(Boost_FOUND) -# include_directories(${Boost_INCLUDE_DIRS}) -# add_executable(foo foo.cc) -# endif() -# -# Example to find Boost libraries and use imported targets:: -# -# find_package(Boost 1.56 REQUIRED COMPONENTS -# date_time filesystem iostreams) -# add_executable(foo foo.cc) -# target_link_libraries(foo Boost::date_time Boost::filesystem -# Boost::iostreams) -# -# Example to find Boost Python 3.6 libraries and use imported targets:: -# -# find_package(Boost 1.67 REQUIRED COMPONENTS -# python36 numpy36) -# add_executable(foo foo.cc) -# target_link_libraries(foo Boost::python36 Boost::numpy36) -# -# Example to find Boost headers and some *static* (release only) libraries:: -# -# set(Boost_USE_STATIC_LIBS ON) # only find static libs -# set(Boost_USE_DEBUG_LIBS OFF) # ignore debug libs and -# set(Boost_USE_RELEASE_LIBS ON) # only find release libs -# set(Boost_USE_MULTITHREADED ON) -# set(Boost_USE_STATIC_RUNTIME OFF) -# find_package(Boost 1.66.0 COMPONENTS date_time filesystem system ...) -# if(Boost_FOUND) -# include_directories(${Boost_INCLUDE_DIRS}) -# add_executable(foo foo.cc) -# target_link_libraries(foo ${Boost_LIBRARIES}) -# endif() -# -# Boost CMake -# ^^^^^^^^^^^ -# -# If Boost was built using the boost-cmake project it provides a package -# configuration file for use with find_package's Config mode. This -# module looks for the package configuration file called -# BoostConfig.cmake or boost-config.cmake and stores the result in cache -# entry "Boost_DIR". If found, the package configuration file is loaded -# and this module returns with no further action. See documentation of -# the Boost CMake package configuration for details on what it provides. -# -# Set Boost_NO_BOOST_CMAKE to ON to disable the search for boost-cmake. - -# Save project's policies -cmake_policy(PUSH) -cmake_policy(SET CMP0057 NEW) # if IN_LIST - -#------------------------------------------------------------------------------- -# Before we go searching, check whether boost-cmake is available, unless the -# user specifically asked NOT to search for boost-cmake. -# -# If Boost_DIR is set, this behaves as any find_package call would. If not, -# it looks at BOOST_ROOT and BOOSTROOT to find Boost. -# -if (NOT Boost_NO_BOOST_CMAKE) - # If Boost_DIR is not set, look for BOOSTROOT and BOOST_ROOT as alternatives, - # since these are more conventional for Boost. - if ("$ENV{Boost_DIR}" STREQUAL "") - if (NOT "$ENV{BOOST_ROOT}" STREQUAL "") - set(ENV{Boost_DIR} $ENV{BOOST_ROOT}) - elseif (NOT "$ENV{BOOSTROOT}" STREQUAL "") - set(ENV{Boost_DIR} $ENV{BOOSTROOT}) - endif() - endif() - - # Do the same find_package call but look specifically for the CMake version. - # Note that args are passed in the Boost_FIND_xxxxx variables, so there is no - # need to delegate them to this find_package call. - find_package(Boost QUIET NO_MODULE) - mark_as_advanced(Boost_DIR) - - # If we found boost-cmake, then we're done. Print out what we found. - # Otherwise let the rest of the module try to find it. - if (Boost_FOUND) - message(STATUS "Boost ${Boost_FIND_VERSION} found.") - if (Boost_FIND_COMPONENTS) - message(STATUS "Found Boost components:\n ${Boost_FIND_COMPONENTS}") - endif() - # Restore project's policies - cmake_policy(POP) - return() - endif() -endif() - - -#------------------------------------------------------------------------------- -# FindBoost functions & macros -# - -############################################ -# -# Check the existence of the libraries. -# -############################################ -# This macro was taken directly from the FindQt4.cmake file that is included -# with the CMake distribution. This is NOT my work. All work was done by the -# original authors of the FindQt4.cmake file. Only minor modifications were -# made to remove references to Qt and make this file more generally applicable -# And ELSE/ENDIF pairs were removed for readability. -######################################################################### - -macro(_Boost_ADJUST_LIB_VARS basename) - if(Boost_INCLUDE_DIR ) - if(Boost_${basename}_LIBRARY_DEBUG AND Boost_${basename}_LIBRARY_RELEASE) - # if the generator is multi-config or if CMAKE_BUILD_TYPE is set for - # single-config generators, set optimized and debug libraries - get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) - if(_isMultiConfig OR CMAKE_BUILD_TYPE) - set(Boost_${basename}_LIBRARY optimized ${Boost_${basename}_LIBRARY_RELEASE} debug ${Boost_${basename}_LIBRARY_DEBUG}) - else() - # For single-config generators where CMAKE_BUILD_TYPE has no value, - # just use the release libraries - set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE} ) - endif() - # FIXME: This probably should be set for both cases - set(Boost_${basename}_LIBRARIES optimized ${Boost_${basename}_LIBRARY_RELEASE} debug ${Boost_${basename}_LIBRARY_DEBUG}) - endif() - - # if only the release version was found, set the debug variable also to the release version - if(Boost_${basename}_LIBRARY_RELEASE AND NOT Boost_${basename}_LIBRARY_DEBUG) - set(Boost_${basename}_LIBRARY_DEBUG ${Boost_${basename}_LIBRARY_RELEASE}) - set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE}) - set(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_RELEASE}) - endif() - - # if only the debug version was found, set the release variable also to the debug version - if(Boost_${basename}_LIBRARY_DEBUG AND NOT Boost_${basename}_LIBRARY_RELEASE) - set(Boost_${basename}_LIBRARY_RELEASE ${Boost_${basename}_LIBRARY_DEBUG}) - set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_DEBUG}) - set(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_DEBUG}) - endif() - - # If the debug & release library ends up being the same, omit the keywords - if("${Boost_${basename}_LIBRARY_RELEASE}" STREQUAL "${Boost_${basename}_LIBRARY_DEBUG}") - set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE} ) - set(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_RELEASE} ) - endif() - - if(Boost_${basename}_LIBRARY AND Boost_${basename}_HEADER) - set(Boost_${basename}_FOUND ON) - if("x${basename}" STREQUAL "xTHREAD" AND NOT TARGET Threads::Threads) - string(APPEND Boost_ERROR_REASON_THREAD " (missing dependency: Threads)") - set(Boost_THREAD_FOUND OFF) - endif() - endif() - - endif() - # Make variables changeable to the advanced user - mark_as_advanced( - Boost_${basename}_LIBRARY_RELEASE - Boost_${basename}_LIBRARY_DEBUG - ) -endmacro() - -# Detect changes in used variables. -# Compares the current variable value with the last one. -# In short form: -# v != v_LAST -> CHANGED = 1 -# v is defined, v_LAST not -> CHANGED = 1 -# v is not defined, but v_LAST is -> CHANGED = 1 -# otherwise -> CHANGED = 0 -# CHANGED is returned in variable named ${changed_var} -macro(_Boost_CHANGE_DETECT changed_var) - set(${changed_var} 0) - foreach(v ${ARGN}) - if(DEFINED _Boost_COMPONENTS_SEARCHED) - if(${v}) - if(_${v}_LAST) - string(COMPARE NOTEQUAL "${${v}}" "${_${v}_LAST}" _${v}_CHANGED) - else() - set(_${v}_CHANGED 1) - endif() - elseif(_${v}_LAST) - set(_${v}_CHANGED 1) - endif() - if(_${v}_CHANGED) - set(${changed_var} 1) - endif() - else() - set(_${v}_CHANGED 0) - endif() - endforeach() -endmacro() - -# -# Find the given library (var). -# Use 'build_type' to support different lib paths for RELEASE or DEBUG builds -# -macro(_Boost_FIND_LIBRARY var build_type) - - find_library(${var} ${ARGN}) - - if(${var}) - # If this is the first library found then save Boost_LIBRARY_DIR_[RELEASE,DEBUG]. - if(NOT Boost_LIBRARY_DIR_${build_type}) - get_filename_component(_dir "${${var}}" PATH) - set(Boost_LIBRARY_DIR_${build_type} "${_dir}" CACHE PATH "Boost library directory ${build_type}" FORCE) - endif() - elseif(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT) - # Try component-specific hints but do not save Boost_LIBRARY_DIR_[RELEASE,DEBUG]. - find_library(${var} HINTS ${_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT} ${ARGN}) - endif() - - # If Boost_LIBRARY_DIR_[RELEASE,DEBUG] is known then search only there. - if(Boost_LIBRARY_DIR_${build_type}) - set(_boost_LIBRARY_SEARCH_DIRS_${build_type} ${Boost_LIBRARY_DIR_${build_type}} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) - if(Boost_DEBUG) - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - " Boost_LIBRARY_DIR_${build_type} = ${Boost_LIBRARY_DIR_${build_type}}" - " _boost_LIBRARY_SEARCH_DIRS_${build_type} = ${_boost_LIBRARY_SEARCH_DIRS_${build_type}}") - endif() - endif() -endmacro() - -#------------------------------------------------------------------------------- - -# -# Runs compiler with "-dumpversion" and parses major/minor -# version with a regex. -# -function(_Boost_COMPILER_DUMPVERSION _OUTPUT_VERSION _OUTPUT_VERSION_MAJOR _OUTPUT_VERSION_MINOR) - string(REGEX REPLACE "([0-9]+)\\.([0-9]+)(\\.[0-9]+)?" "\\1" - _boost_COMPILER_VERSION_MAJOR ${CMAKE_CXX_COMPILER_VERSION}) - string(REGEX REPLACE "([0-9]+)\\.([0-9]+)(\\.[0-9]+)?" "\\2" - _boost_COMPILER_VERSION_MINOR ${CMAKE_CXX_COMPILER_VERSION}) - - set(_boost_COMPILER_VERSION "${_boost_COMPILER_VERSION_MAJOR}${_boost_COMPILER_VERSION_MINOR}") - - set(${_OUTPUT_VERSION} ${_boost_COMPILER_VERSION} PARENT_SCOPE) - set(${_OUTPUT_VERSION_MAJOR} ${_boost_COMPILER_VERSION_MAJOR} PARENT_SCOPE) - set(${_OUTPUT_VERSION_MINOR} ${_boost_COMPILER_VERSION_MINOR} PARENT_SCOPE) -endfunction() - -# -# Take a list of libraries with "thread" in it -# and prepend duplicates with "thread_${Boost_THREADAPI}" -# at the front of the list -# -function(_Boost_PREPEND_LIST_WITH_THREADAPI _output) - set(_orig_libnames ${ARGN}) - string(REPLACE "thread" "thread_${Boost_THREADAPI}" _threadapi_libnames "${_orig_libnames}") - set(${_output} ${_threadapi_libnames} ${_orig_libnames} PARENT_SCOPE) -endfunction() - -# -# If a library is found, replace its cache entry with its REALPATH -# -function(_Boost_SWAP_WITH_REALPATH _library _docstring) - if(${_library}) - get_filename_component(_boost_filepathreal ${${_library}} REALPATH) - unset(${_library} CACHE) - set(${_library} ${_boost_filepathreal} CACHE FILEPATH "${_docstring}") - endif() -endfunction() - -function(_Boost_CHECK_SPELLING _var) - if(${_var}) - string(TOUPPER ${_var} _var_UC) - message(FATAL_ERROR "ERROR: ${_var} is not the correct spelling. The proper spelling is ${_var_UC}.") - endif() -endfunction() - -# Guesses Boost's compiler prefix used in built library names -# Returns the guess by setting the variable pointed to by _ret -function(_Boost_GUESS_COMPILER_PREFIX _ret) - if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xIntel") - if(WIN32) - set (_boost_COMPILER "-iw") - else() - set (_boost_COMPILER "-il") - endif() - elseif (GHSMULTI) - set(_boost_COMPILER "-ghs") - elseif("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC") - if(MSVC_TOOLSET_VERSION GREATER_EQUAL 141) - set(_boost_COMPILER "-vc141;-vc140") - elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 80) - set(_boost_COMPILER "-vc${MSVC_TOOLSET_VERSION}") - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.10) - set(_boost_COMPILER "-vc71") - elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13) # Good luck! - set(_boost_COMPILER "-vc7") # yes, this is correct - else() # VS 6.0 Good luck! - set(_boost_COMPILER "-vc6") # yes, this is correct - endif() - elseif (BORLAND) - set(_boost_COMPILER "-bcb") - elseif(CMAKE_CXX_COMPILER_ID STREQUAL "SunPro") - set(_boost_COMPILER "-sw") - elseif(CMAKE_CXX_COMPILER_ID STREQUAL "XL") - set(_boost_COMPILER "-xlc") - elseif (MINGW) - if(${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.34) - set(_boost_COMPILER "-mgw") # no GCC version encoding prior to 1.34 - else() - _Boost_COMPILER_DUMPVERSION(_boost_COMPILER_VERSION _boost_COMPILER_VERSION_MAJOR _boost_COMPILER_VERSION_MINOR) - set(_boost_COMPILER "-mgw${_boost_COMPILER_VERSION}") - endif() - elseif (UNIX) - _Boost_COMPILER_DUMPVERSION(_boost_COMPILER_VERSION _boost_COMPILER_VERSION_MAJOR _boost_COMPILER_VERSION_MINOR) - if(NOT Boost_VERSION VERSION_LESS 106900) - # From GCC 5 and clang 4, versioning changes and minor becomes patch. - # For those compilers, patch is exclude from compiler tag in Boost 1.69+ library naming. - if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND _boost_COMPILER_VERSION_MAJOR VERSION_GREATER 4) - set(_boost_COMPILER_VERSION "${_boost_COMPILER_VERSION_MAJOR}") - elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND _boost_COMPILER_VERSION_MAJOR VERSION_GREATER 3) - set(_boost_COMPILER_VERSION "${_boost_COMPILER_VERSION_MAJOR}") - endif() - endif() - - if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - if(${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.34) - set(_boost_COMPILER "-gcc") # no GCC version encoding prior to 1.34 - else() - # Determine which version of GCC we have. - if(APPLE) - if(Boost_MINOR_VERSION) - if(${Boost_MINOR_VERSION} GREATER 35) - # In Boost 1.36.0 and newer, the mangled compiler name used - # on macOS/Darwin is "xgcc". - set(_boost_COMPILER "-xgcc${_boost_COMPILER_VERSION}") - else() - # In Boost <= 1.35.0, there is no mangled compiler name for - # the macOS/Darwin version of GCC. - set(_boost_COMPILER "") - endif() - else() - # We don't know the Boost version, so assume it's - # pre-1.36.0. - set(_boost_COMPILER "") - endif() - else() - set(_boost_COMPILER "-gcc${_boost_COMPILER_VERSION}") - endif() - endif() - elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - # TODO: Find out any Boost version constraints vs clang support. - set(_boost_COMPILER "-clang${_boost_COMPILER_VERSION}") - endif() - else() - # TODO at least Boost_DEBUG here? - set(_boost_COMPILER "") - endif() - set(${_ret} ${_boost_COMPILER} PARENT_SCOPE) -endfunction() - -# -# Get component dependencies. Requires the dependencies to have been -# defined for the Boost release version. -# -# component - the component to check -# _ret - list of library dependencies -# -function(_Boost_COMPONENT_DEPENDENCIES component _ret) - # Note: to add a new Boost release, run - # - # % cmake -DBOOST_DIR=/path/to/boost/source -P Utilities/Scripts/BoostScanDeps.cmake - # - # The output may be added in a new block below. If it's the same as - # the previous release, simply update the version range of the block - # for the previous release. Also check if any new components have - # been added, and add any new components to - # _Boost_COMPONENT_HEADERS. - # - # This information was originally generated by running - # BoostScanDeps.cmake against every boost release to date supported - # by FindBoost: - # - # % for version in /path/to/boost/sources/* - # do - # cmake -DBOOST_DIR=$version -P Utilities/Scripts/BoostScanDeps.cmake - # done - # - # The output was then updated by search and replace with these regexes: - # - # - Strip message(STATUS) prefix dashes - # s;^-- ;; - # - Indent - # s;^set(; set(;; - # - Add conditionals - # s;Scanning /path/to/boost/sources/boost_\(.*\)_\(.*\)_\(.*); elseif(NOT Boost_VERSION VERSION_LESS \10\20\3 AND Boost_VERSION VERSION_LESS xxxx); - # - # This results in the logic seen below, but will require the xxxx - # replacing with the following Boost release version (or the next - # minor version to be released, e.g. 1.59 was the latest at the time - # of writing, making 1.60 the next, so 106000 is the needed version - # number). Identical consecutive releases were then merged together - # by updating the end range of the first block and removing the - # following redundant blocks. - # - # Running the script against all historical releases should be - # required only if the BoostScanDeps.cmake script logic is changed. - # The addition of a new release should only require it to be run - # against the new release. - - # Handle Python version suffixes - if(component MATCHES "^(python|mpi_python|numpy)([0-9][0-9]?|[0-9]\\.[0-9])\$") - set(component "${CMAKE_MATCH_1}") - set(component_python_version "${CMAKE_MATCH_2}") - endif() - - set(_Boost_IMPORTED_TARGETS TRUE) - if(Boost_VERSION AND Boost_VERSION VERSION_LESS 103300) - message(WARNING "Imported targets and dependency information not available for Boost version ${Boost_VERSION} (all versions older than 1.33)") - set(_Boost_IMPORTED_TARGETS FALSE) - elseif(NOT Boost_VERSION VERSION_LESS 103300 AND Boost_VERSION VERSION_LESS 103500) - set(_Boost_IOSTREAMS_DEPENDENCIES regex thread) - set(_Boost_REGEX_DEPENDENCIES thread) - set(_Boost_WAVE_DEPENDENCIES filesystem thread) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 103500 AND Boost_VERSION VERSION_LESS 103600) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_WAVE_DEPENDENCIES filesystem system thread) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 103600 AND Boost_VERSION VERSION_LESS 103800) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_WAVE_DEPENDENCIES filesystem system thread) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 103800 AND Boost_VERSION VERSION_LESS 104300) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES date_time) - set(_Boost_WAVE_DEPENDENCIES filesystem system thread date_time) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 104300 AND Boost_VERSION VERSION_LESS 104400) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES date_time) - set(_Boost_WAVE_DEPENDENCIES filesystem system thread date_time) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 104400 AND Boost_VERSION VERSION_LESS 104500) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random serialization) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES date_time) - set(_Boost_WAVE_DEPENDENCIES serialization filesystem system thread date_time) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 104500 AND Boost_VERSION VERSION_LESS 104700) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES date_time) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 104700 AND Boost_VERSION VERSION_LESS 104800) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES date_time) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 104800 AND Boost_VERSION VERSION_LESS 105000) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES date_time) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 105000 AND Boost_VERSION VERSION_LESS 105300) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 105300 AND Boost_VERSION VERSION_LESS 105400) - set(_Boost_ATOMIC_DEPENDENCIES thread chrono system date_time) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 105400 AND Boost_VERSION VERSION_LESS 105500) - set(_Boost_ATOMIC_DEPENDENCIES thread chrono system date_time) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 105500 AND Boost_VERSION VERSION_LESS 105600) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 105600 AND Boost_VERSION VERSION_LESS 105900) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_RANDOM_DEPENDENCIES system) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 105900 AND Boost_VERSION VERSION_LESS 106000) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_RANDOM_DEPENDENCIES system) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 106000 AND Boost_VERSION VERSION_LESS 106100) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_RANDOM_DEPENDENCIES system) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 106100 AND Boost_VERSION VERSION_LESS 106200) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_RANDOM_DEPENDENCIES system) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 106200 AND Boost_VERSION VERSION_LESS 106300) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_RANDOM_DEPENDENCIES system) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 106300 AND Boost_VERSION VERSION_LESS 106500) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_COROUTINE2_DEPENDENCIES context fiber thread chrono system date_time) - set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_RANDOM_DEPENDENCIES system) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 106500 AND Boost_VERSION VERSION_LESS 106700) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) - set(_Boost_RANDOM_DEPENDENCIES system) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 106700 AND Boost_VERSION VERSION_LESS 106800) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) - set(_Boost_RANDOM_DEPENDENCIES system) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - elseif(NOT Boost_VERSION VERSION_LESS 106800 AND Boost_VERSION VERSION_LESS 106900) - set(_Boost_CHRONO_DEPENDENCIES system) - set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) - set(_Boost_CONTRACT_DEPENDENCIES thread chrono system date_time) - set(_Boost_COROUTINE_DEPENDENCIES context system) - set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time) - set(_Boost_FILESYSTEM_DEPENDENCIES system) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) - set(_Boost_RANDOM_DEPENDENCIES system) - set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - else() - if(NOT Boost_VERSION VERSION_LESS 106900) - set(_Boost_CONTRACT_DEPENDENCIES thread chrono date_time) - set(_Boost_COROUTINE_DEPENDENCIES context) - set(_Boost_FIBER_DEPENDENCIES context) - set(_Boost_IOSTREAMS_DEPENDENCIES regex) - set(_Boost_LOG_DEPENDENCIES date_time log_setup filesystem thread regex chrono atomic) - set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) - set(_Boost_MPI_DEPENDENCIES serialization) - set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization) - set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) - set(_Boost_THREAD_DEPENDENCIES chrono date_time atomic) - set(_Boost_TIMER_DEPENDENCIES chrono system) - set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono date_time atomic) - set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) - endif() - if(NOT Boost_VERSION VERSION_LESS 107000) - message(WARNING "New Boost version may have incorrect or missing dependencies and imported targets") - endif() - endif() - - string(TOUPPER ${component} uppercomponent) - set(${_ret} ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE) - set(_Boost_IMPORTED_TARGETS ${_Boost_IMPORTED_TARGETS} PARENT_SCOPE) - - string(REGEX REPLACE ";" " " _boost_DEPS_STRING "${_Boost_${uppercomponent}_DEPENDENCIES}") - if (NOT _boost_DEPS_STRING) - set(_boost_DEPS_STRING "(none)") - endif() - # message(STATUS "Dependencies for Boost::${component}: ${_boost_DEPS_STRING}") -endfunction() - -# -# Get component headers. This is the primary header (or headers) for -# a given component, and is used to check that the headers are present -# as well as the library itself as an extra sanity check of the build -# environment. -# -# component - the component to check -# _hdrs -# -function(_Boost_COMPONENT_HEADERS component _hdrs) - # Handle Python version suffixes - if(component MATCHES "^(python|mpi_python|numpy)([0-9][0-9]?|[0-9]\\.[0-9])\$") - set(component "${CMAKE_MATCH_1}") - set(component_python_version "${CMAKE_MATCH_2}") - endif() - - # Note: new boost components will require adding here. The header - # must be present in all versions of Boost providing a library. - set(_Boost_ATOMIC_HEADERS "boost/atomic.hpp") - set(_Boost_CHRONO_HEADERS "boost/chrono.hpp") - set(_Boost_CONTAINER_HEADERS "boost/container/container_fwd.hpp") - set(_Boost_CONTRACT_HEADERS "boost/contract.hpp") - if(Boost_VERSION VERSION_LESS 106100) - set(_Boost_CONTEXT_HEADERS "boost/context/all.hpp") - else() - set(_Boost_CONTEXT_HEADERS "boost/context/detail/fcontext.hpp") - endif() - set(_Boost_COROUTINE_HEADERS "boost/coroutine/all.hpp") - set(_Boost_DATE_TIME_HEADERS "boost/date_time/date.hpp") - set(_Boost_EXCEPTION_HEADERS "boost/exception/exception.hpp") - set(_Boost_FIBER_HEADERS "boost/fiber/all.hpp") - set(_Boost_FILESYSTEM_HEADERS "boost/filesystem/path.hpp") - set(_Boost_GRAPH_HEADERS "boost/graph/adjacency_list.hpp") - set(_Boost_GRAPH_PARALLEL_HEADERS "boost/graph/adjacency_list.hpp") - set(_Boost_IOSTREAMS_HEADERS "boost/iostreams/stream.hpp") - set(_Boost_LOCALE_HEADERS "boost/locale.hpp") - set(_Boost_LOG_HEADERS "boost/log/core.hpp") - set(_Boost_LOG_SETUP_HEADERS "boost/log/detail/setup_config.hpp") - set(_Boost_MATH_HEADERS "boost/math_fwd.hpp") - set(_Boost_MATH_C99_HEADERS "boost/math/tr1.hpp") - set(_Boost_MATH_C99F_HEADERS "boost/math/tr1.hpp") - set(_Boost_MATH_C99L_HEADERS "boost/math/tr1.hpp") - set(_Boost_MATH_TR1_HEADERS "boost/math/tr1.hpp") - set(_Boost_MATH_TR1F_HEADERS "boost/math/tr1.hpp") - set(_Boost_MATH_TR1L_HEADERS "boost/math/tr1.hpp") - set(_Boost_MPI_HEADERS "boost/mpi.hpp") - set(_Boost_MPI_PYTHON_HEADERS "boost/mpi/python/config.hpp") - set(_Boost_NUMPY_HEADERS "boost/python/numpy.hpp") - set(_Boost_PRG_EXEC_MONITOR_HEADERS "boost/test/prg_exec_monitor.hpp") - set(_Boost_PROGRAM_OPTIONS_HEADERS "boost/program_options.hpp") - set(_Boost_PYTHON_HEADERS "boost/python.hpp") - set(_Boost_RANDOM_HEADERS "boost/random.hpp") - set(_Boost_REGEX_HEADERS "boost/regex.hpp") - set(_Boost_SERIALIZATION_HEADERS "boost/serialization/serialization.hpp") - set(_Boost_SIGNALS_HEADERS "boost/signals.hpp") - set(_Boost_STACKTRACE_ADDR2LINE_HEADERS "boost/stacktrace.hpp") - set(_Boost_STACKTRACE_BACKTRACE_HEADERS "boost/stacktrace.hpp") - set(_Boost_STACKTRACE_BASIC_HEADERS "boost/stacktrace.hpp") - set(_Boost_STACKTRACE_NOOP_HEADERS "boost/stacktrace.hpp") - set(_Boost_STACKTRACE_WINDBG_CACHED_HEADERS "boost/stacktrace.hpp") - set(_Boost_STACKTRACE_WINDBG_HEADERS "boost/stacktrace.hpp") - set(_Boost_SYSTEM_HEADERS "boost/system/config.hpp") - set(_Boost_TEST_EXEC_MONITOR_HEADERS "boost/test/test_exec_monitor.hpp") - set(_Boost_THREAD_HEADERS "boost/thread.hpp") - set(_Boost_TIMER_HEADERS "boost/timer.hpp") - set(_Boost_TYPE_ERASURE_HEADERS "boost/type_erasure/config.hpp") - set(_Boost_UNIT_TEST_FRAMEWORK_HEADERS "boost/test/framework.hpp") - set(_Boost_WAVE_HEADERS "boost/wave.hpp") - set(_Boost_WSERIALIZATION_HEADERS "boost/archive/text_wiarchive.hpp") - if(WIN32) - set(_Boost_BZIP2_HEADERS "boost/iostreams/filter/bzip2.hpp") - set(_Boost_ZLIB_HEADERS "boost/iostreams/filter/zlib.hpp") - endif() - - string(TOUPPER ${component} uppercomponent) - set(${_hdrs} ${_Boost_${uppercomponent}_HEADERS} PARENT_SCOPE) - - string(REGEX REPLACE ";" " " _boost_HDRS_STRING "${_Boost_${uppercomponent}_HEADERS}") - if (NOT _boost_HDRS_STRING) - set(_boost_HDRS_STRING "(none)") - endif() - # message(STATUS "Headers for Boost::${component}: ${_boost_HDRS_STRING}") -endfunction() - -# -# Determine if any missing dependencies require adding to the component list. -# -# Sets _Boost_${COMPONENT}_DEPENDENCIES for each required component, -# plus _Boost_IMPORTED_TARGETS (TRUE if imported targets should be -# defined; FALSE if dependency information is unavailable). -# -# componentvar - the component list variable name -# extravar - the indirect dependency list variable name -# -# -function(_Boost_MISSING_DEPENDENCIES componentvar extravar) - # _boost_unprocessed_components - list of components requiring processing - # _boost_processed_components - components already processed (or currently being processed) - # _boost_new_components - new components discovered for future processing - # - list(APPEND _boost_unprocessed_components ${${componentvar}}) - - while(_boost_unprocessed_components) - list(APPEND _boost_processed_components ${_boost_unprocessed_components}) - foreach(component ${_boost_unprocessed_components}) - string(TOUPPER ${component} uppercomponent) - set(${_ret} ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE) - _Boost_COMPONENT_DEPENDENCIES("${component}" _Boost_${uppercomponent}_DEPENDENCIES) - set(_Boost_${uppercomponent}_DEPENDENCIES ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE) - set(_Boost_IMPORTED_TARGETS ${_Boost_IMPORTED_TARGETS} PARENT_SCOPE) - foreach(componentdep ${_Boost_${uppercomponent}_DEPENDENCIES}) - if (NOT ("${componentdep}" IN_LIST _boost_processed_components OR "${componentdep}" IN_LIST _boost_new_components)) - list(APPEND _boost_new_components ${componentdep}) - endif() - endforeach() - endforeach() - set(_boost_unprocessed_components ${_boost_new_components}) - unset(_boost_new_components) - endwhile() - set(_boost_extra_components ${_boost_processed_components}) - if(_boost_extra_components AND ${componentvar}) - list(REMOVE_ITEM _boost_extra_components ${${componentvar}}) - endif() - set(${componentvar} ${_boost_processed_components} PARENT_SCOPE) - set(${extravar} ${_boost_extra_components} PARENT_SCOPE) -endfunction() - -# -# Some boost libraries may require particular set of compler features. -# The very first one was `boost::fiber` introduced in Boost 1.62. -# One can check required compiler features of it in -# `${Boost_ROOT}/libs/fiber/build/Jamfile.v2`. -# -function(_Boost_COMPILER_FEATURES component _ret) - # Boost >= 1.62 and < 1.67 - if(NOT Boost_VERSION VERSION_LESS 106200 AND Boost_VERSION VERSION_LESS 106700) - set(_Boost_FIBER_COMPILER_FEATURES - cxx_alias_templates - cxx_auto_type - cxx_constexpr - cxx_defaulted_functions - cxx_final - cxx_lambdas - cxx_noexcept - cxx_nullptr - cxx_rvalue_references - cxx_thread_local - cxx_variadic_templates - ) - endif() - string(TOUPPER ${component} uppercomponent) - set(${_ret} ${_Boost_${uppercomponent}_COMPILER_FEATURES} PARENT_SCOPE) -endfunction() - -# -# Update library search directory hint variable with paths used by prebuilt boost binaries. -# -# Prebuilt windows binaries (https://sourceforge.net/projects/boost/files/boost-binaries/) -# have library directories named using MSVC compiler version and architecture. -# This function would append corresponding directories if MSVC is a current compiler, -# so having `BOOST_ROOT` would be enough to specify to find everything. -# -function(_Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS componentlibvar basedir) - if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC") - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(_arch_suffix 64) - else() - set(_arch_suffix 32) - endif() - if(MSVC_TOOLSET_VERSION GREATER_EQUAL 141) - list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-14.1) - list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-14.0) - elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 80) - math(EXPR _toolset_major_version "${MSVC_TOOLSET_VERSION} / 10") - list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-${_toolset_major_version}.0) - endif() - set(${componentlibvar} ${${componentlibvar}} PARENT_SCOPE) - endif() -endfunction() - -# -# End functions/macros -# -#------------------------------------------------------------------------------- - -#------------------------------------------------------------------------------- -# main. -#------------------------------------------------------------------------------- - - -# If the user sets Boost_LIBRARY_DIR, use it as the default for both -# configurations. -if(NOT Boost_LIBRARY_DIR_RELEASE AND Boost_LIBRARY_DIR) - set(Boost_LIBRARY_DIR_RELEASE "${Boost_LIBRARY_DIR}") -endif() -if(NOT Boost_LIBRARY_DIR_DEBUG AND Boost_LIBRARY_DIR) - set(Boost_LIBRARY_DIR_DEBUG "${Boost_LIBRARY_DIR}") -endif() - -if(NOT DEFINED Boost_USE_DEBUG_LIBS) - set(Boost_USE_DEBUG_LIBS TRUE) -endif() -if(NOT DEFINED Boost_USE_RELEASE_LIBS) - set(Boost_USE_RELEASE_LIBS TRUE) -endif() -if(NOT DEFINED Boost_USE_MULTITHREADED) - set(Boost_USE_MULTITHREADED TRUE) -endif() -if(NOT DEFINED Boost_USE_DEBUG_RUNTIME) - set(Boost_USE_DEBUG_RUNTIME TRUE) -endif() - -# Check the version of Boost against the requested version. -if(Boost_FIND_VERSION AND NOT Boost_FIND_VERSION_MINOR) - message(SEND_ERROR "When requesting a specific version of Boost, you must provide at least the major and minor version numbers, e.g., 1.34") -endif() - -if(Boost_FIND_VERSION_EXACT) - # The version may appear in a directory with or without the patch - # level, even when the patch level is non-zero. - set(_boost_TEST_VERSIONS - "${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}.${Boost_FIND_VERSION_PATCH}" - "${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}") -else() - # The user has not requested an exact version. Among known - # versions, find those that are acceptable to the user request. - # - # Note: When adding a new Boost release, also update the dependency - # information in _Boost_COMPONENT_DEPENDENCIES and - # _Boost_COMPONENT_HEADERS. See the instructions at the top of - # _Boost_COMPONENT_DEPENDENCIES. - set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS} - "1.69.0" "1.69" - "1.68.0" "1.68" "1.67.0" "1.67" "1.66.0" "1.66" "1.65.1" "1.65.0" "1.65" - "1.64.0" "1.64" "1.63.0" "1.63" "1.62.0" "1.62" "1.61.0" "1.61" "1.60.0" "1.60" - "1.59.0" "1.59" "1.58.0" "1.58" "1.57.0" "1.57" "1.56.0" "1.56" "1.55.0" "1.55" - "1.54.0" "1.54" "1.53.0" "1.53" "1.52.0" "1.52" "1.51.0" "1.51" - "1.50.0" "1.50" "1.49.0" "1.49" "1.48.0" "1.48" "1.47.0" "1.47" "1.46.1" - "1.46.0" "1.46" "1.45.0" "1.45" "1.44.0" "1.44" "1.43.0" "1.43" "1.42.0" "1.42" - "1.41.0" "1.41" "1.40.0" "1.40" "1.39.0" "1.39" "1.38.0" "1.38" "1.37.0" "1.37" - "1.36.1" "1.36.0" "1.36" "1.35.1" "1.35.0" "1.35" "1.34.1" "1.34.0" - "1.34" "1.33.1" "1.33.0" "1.33") - - set(_boost_TEST_VERSIONS) - if(Boost_FIND_VERSION) - set(_Boost_FIND_VERSION_SHORT "${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}") - # Select acceptable versions. - foreach(version ${_Boost_KNOWN_VERSIONS}) - if(NOT "${version}" VERSION_LESS "${Boost_FIND_VERSION}") - # This version is high enough. - list(APPEND _boost_TEST_VERSIONS "${version}") - elseif("${version}.99" VERSION_EQUAL "${_Boost_FIND_VERSION_SHORT}.99") - # This version is a short-form for the requested version with - # the patch level dropped. - list(APPEND _boost_TEST_VERSIONS "${version}") - endif() - endforeach() - else() - # Any version is acceptable. - set(_boost_TEST_VERSIONS "${_Boost_KNOWN_VERSIONS}") - endif() -endif() - -# The reason that we failed to find Boost. This will be set to a -# user-friendly message when we fail to find some necessary piece of -# Boost. -set(Boost_ERROR_REASON) - -if(Boost_DEBUG) - # Output some of their choices - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "_boost_TEST_VERSIONS = ${_boost_TEST_VERSIONS}") - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "Boost_USE_MULTITHREADED = ${Boost_USE_MULTITHREADED}") - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "Boost_USE_STATIC_LIBS = ${Boost_USE_STATIC_LIBS}") - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "Boost_USE_STATIC_RUNTIME = ${Boost_USE_STATIC_RUNTIME}") - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "Boost_ADDITIONAL_VERSIONS = ${Boost_ADDITIONAL_VERSIONS}") - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "Boost_NO_SYSTEM_PATHS = ${Boost_NO_SYSTEM_PATHS}") -endif() - -# Supply Boost_LIB_DIAGNOSTIC_DEFINITIONS as a convenience target. It -# will only contain any interface definitions on WIN32, but is created -# on all platforms to keep end user code free from platform dependent -# code. Also provide convenience targets to disable autolinking and -# enable dynamic linking. -if(NOT TARGET Boost::diagnostic_definitions) - add_library(Boost::diagnostic_definitions INTERFACE IMPORTED) - add_library(Boost::disable_autolinking INTERFACE IMPORTED) - add_library(Boost::dynamic_linking INTERFACE IMPORTED) -endif() -if(WIN32) - # In windows, automatic linking is performed, so you do not have - # to specify the libraries. If you are linking to a dynamic - # runtime, then you can choose to link to either a static or a - # dynamic Boost library, the default is to do a static link. You - # can alter this for a specific library "whatever" by defining - # BOOST_WHATEVER_DYN_LINK to force Boost library "whatever" to be - # linked dynamically. Alternatively you can force all Boost - # libraries to dynamic link by defining BOOST_ALL_DYN_LINK. - - # This feature can be disabled for Boost library "whatever" by - # defining BOOST_WHATEVER_NO_LIB, or for all of Boost by defining - # BOOST_ALL_NO_LIB. - - # If you want to observe which libraries are being linked against - # then defining BOOST_LIB_DIAGNOSTIC will cause the auto-linking - # code to emit a #pragma message each time a library is selected - # for linking. - set(Boost_LIB_DIAGNOSTIC_DEFINITIONS "-DBOOST_LIB_DIAGNOSTIC") - set_target_properties(Boost::diagnostic_definitions PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "BOOST_LIB_DIAGNOSTIC") - set_target_properties(Boost::disable_autolinking PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_NO_LIB") - set_target_properties(Boost::dynamic_linking PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_DYN_LINK") -endif() - -_Boost_CHECK_SPELLING(Boost_ROOT) -_Boost_CHECK_SPELLING(Boost_LIBRARYDIR) -_Boost_CHECK_SPELLING(Boost_INCLUDEDIR) - -# Collect environment variable inputs as hints. Do not consider changes. -foreach(v BOOSTROOT BOOST_ROOT BOOST_INCLUDEDIR BOOST_LIBRARYDIR) - set(_env $ENV{${v}}) - if(_env) - file(TO_CMAKE_PATH "${_env}" _ENV_${v}) - else() - set(_ENV_${v} "") - endif() -endforeach() -if(NOT _ENV_BOOST_ROOT AND _ENV_BOOSTROOT) - set(_ENV_BOOST_ROOT "${_ENV_BOOSTROOT}") -endif() - -# Collect inputs and cached results. Detect changes since the last run. -if(NOT BOOST_ROOT AND BOOSTROOT) - set(BOOST_ROOT "${BOOSTROOT}") -endif() -set(_Boost_VARS_DIR - BOOST_ROOT - Boost_NO_SYSTEM_PATHS - ) - -if(Boost_DEBUG) - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "Declared as CMake or Environmental Variables:") - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - " BOOST_ROOT = ${BOOST_ROOT}") - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - " BOOST_INCLUDEDIR = ${BOOST_INCLUDEDIR}") - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - " BOOST_LIBRARYDIR = ${BOOST_LIBRARYDIR}") - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "_boost_TEST_VERSIONS = ${_boost_TEST_VERSIONS}") -endif() - -# ------------------------------------------------------------------------ -# Search for Boost include DIR -# ------------------------------------------------------------------------ - -set(_Boost_VARS_INC BOOST_INCLUDEDIR Boost_INCLUDE_DIR Boost_ADDITIONAL_VERSIONS) -_Boost_CHANGE_DETECT(_Boost_CHANGE_INCDIR ${_Boost_VARS_DIR} ${_Boost_VARS_INC}) -# Clear Boost_INCLUDE_DIR if it did not change but other input affecting the -# location did. We will find a new one based on the new inputs. -if(_Boost_CHANGE_INCDIR AND NOT _Boost_INCLUDE_DIR_CHANGED) - unset(Boost_INCLUDE_DIR CACHE) -endif() - -if(NOT Boost_INCLUDE_DIR) - set(_boost_INCLUDE_SEARCH_DIRS "") - if(BOOST_INCLUDEDIR) - list(APPEND _boost_INCLUDE_SEARCH_DIRS ${BOOST_INCLUDEDIR}) - elseif(_ENV_BOOST_INCLUDEDIR) - list(APPEND _boost_INCLUDE_SEARCH_DIRS ${_ENV_BOOST_INCLUDEDIR}) - endif() - - if( BOOST_ROOT ) - list(APPEND _boost_INCLUDE_SEARCH_DIRS ${BOOST_ROOT}/include ${BOOST_ROOT}) - elseif( _ENV_BOOST_ROOT ) - list(APPEND _boost_INCLUDE_SEARCH_DIRS ${_ENV_BOOST_ROOT}/include ${_ENV_BOOST_ROOT}) - endif() - - if( Boost_NO_SYSTEM_PATHS) - list(APPEND _boost_INCLUDE_SEARCH_DIRS NO_CMAKE_SYSTEM_PATH NO_SYSTEM_ENVIRONMENT_PATH) - else() - if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC") - foreach(ver ${_Boost_KNOWN_VERSIONS}) - string(REPLACE "." "_" ver "${ver}") - list(APPEND _boost_INCLUDE_SEARCH_DIRS PATHS "C:/local/boost_${ver}") - endforeach() - endif() - list(APPEND _boost_INCLUDE_SEARCH_DIRS PATHS - C:/boost/include - C:/boost - /sw/local/include - ) - endif() - - # Try to find Boost by stepping backwards through the Boost versions - # we know about. - # Build a list of path suffixes for each version. - set(_boost_PATH_SUFFIXES) - foreach(_boost_VER ${_boost_TEST_VERSIONS}) - # Add in a path suffix, based on the required version, ideally - # we could read this from version.hpp, but for that to work we'd - # need to know the include dir already - set(_boost_BOOSTIFIED_VERSION) - - # Transform 1.35 => 1_35 and 1.36.0 => 1_36_0 - if(_boost_VER MATCHES "([0-9]+)\\.([0-9]+)\\.([0-9]+)") - set(_boost_BOOSTIFIED_VERSION - "${CMAKE_MATCH_1}_${CMAKE_MATCH_2}_${CMAKE_MATCH_3}") - elseif(_boost_VER MATCHES "([0-9]+)\\.([0-9]+)") - set(_boost_BOOSTIFIED_VERSION - "${CMAKE_MATCH_1}_${CMAKE_MATCH_2}") - endif() - - list(APPEND _boost_PATH_SUFFIXES - "boost-${_boost_BOOSTIFIED_VERSION}" - "boost_${_boost_BOOSTIFIED_VERSION}" - "boost/boost-${_boost_BOOSTIFIED_VERSION}" - "boost/boost_${_boost_BOOSTIFIED_VERSION}" - ) - - endforeach() - - if(Boost_DEBUG) - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "Include debugging info:") - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - " _boost_INCLUDE_SEARCH_DIRS = ${_boost_INCLUDE_SEARCH_DIRS}") - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - " _boost_PATH_SUFFIXES = ${_boost_PATH_SUFFIXES}") - endif() - - # Look for a standard boost header file. - find_path(Boost_INCLUDE_DIR - NAMES boost/config.hpp - HINTS ${_boost_INCLUDE_SEARCH_DIRS} - PATH_SUFFIXES ${_boost_PATH_SUFFIXES} - ) -endif() - -# ------------------------------------------------------------------------ -# Extract version information from version.hpp -# ------------------------------------------------------------------------ - -# Set Boost_FOUND based only on header location and version. -# It will be updated below for component libraries. -if(Boost_INCLUDE_DIR) - if(Boost_DEBUG) - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "location of version.hpp: ${Boost_INCLUDE_DIR}/boost/version.hpp") - endif() - - # Extract Boost_VERSION and Boost_LIB_VERSION from version.hpp - set(Boost_VERSION 0) - set(Boost_LIB_VERSION "") - file(STRINGS "${Boost_INCLUDE_DIR}/boost/version.hpp" _boost_VERSION_HPP_CONTENTS REGEX "#define BOOST_(LIB_)?VERSION ") - set(_Boost_VERSION_REGEX "([0-9]+)") - set(_Boost_LIB_VERSION_REGEX "\"([0-9_]+)\"") - foreach(v VERSION LIB_VERSION) - if("${_boost_VERSION_HPP_CONTENTS}" MATCHES "#define BOOST_${v} ${_Boost_${v}_REGEX}") - set(Boost_${v} "${CMAKE_MATCH_1}") - endif() - endforeach() - unset(_boost_VERSION_HPP_CONTENTS) - - math(EXPR Boost_MAJOR_VERSION "${Boost_VERSION} / 100000") - math(EXPR Boost_MINOR_VERSION "${Boost_VERSION} / 100 % 1000") - math(EXPR Boost_SUBMINOR_VERSION "${Boost_VERSION} % 100") - - string(APPEND Boost_ERROR_REASON - "Boost version: ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}\nBoost include path: ${Boost_INCLUDE_DIR}") - if(Boost_DEBUG) - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "version.hpp reveals boost " - "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}") - endif() - - if(Boost_FIND_VERSION) - # Set Boost_FOUND based on requested version. - set(_Boost_VERSION "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}") - if("${_Boost_VERSION}" VERSION_LESS "${Boost_FIND_VERSION}") - set(Boost_FOUND 0) - set(_Boost_VERSION_AGE "old") - elseif(Boost_FIND_VERSION_EXACT AND - NOT "${_Boost_VERSION}" VERSION_EQUAL "${Boost_FIND_VERSION}") - set(Boost_FOUND 0) - set(_Boost_VERSION_AGE "new") - else() - set(Boost_FOUND 1) - endif() - if(NOT Boost_FOUND) - # State that we found a version of Boost that is too new or too old. - string(APPEND Boost_ERROR_REASON - "\nDetected version of Boost is too ${_Boost_VERSION_AGE}. Requested version was ${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}") - if (Boost_FIND_VERSION_PATCH) - string(APPEND Boost_ERROR_REASON - ".${Boost_FIND_VERSION_PATCH}") - endif () - if (NOT Boost_FIND_VERSION_EXACT) - string(APPEND Boost_ERROR_REASON " (or newer)") - endif () - string(APPEND Boost_ERROR_REASON ".") - endif () - else() - # Caller will accept any Boost version. - set(Boost_FOUND 1) - endif() -else() - set(Boost_FOUND 0) - string(APPEND Boost_ERROR_REASON - "Unable to find the Boost header files. Please set BOOST_ROOT to the root directory containing Boost or BOOST_INCLUDEDIR to the directory containing Boost's headers.") -endif() - -# ------------------------------------------------------------------------ -# Prefix initialization -# ------------------------------------------------------------------------ - -set(Boost_LIB_PREFIX "") -if ( (GHSMULTI AND Boost_USE_STATIC_LIBS) OR - (WIN32 AND Boost_USE_STATIC_LIBS AND NOT CYGWIN) ) - set(Boost_LIB_PREFIX "lib") -endif() - -if ( NOT Boost_NAMESPACE ) - set(Boost_NAMESPACE "boost") -endif() - -# ------------------------------------------------------------------------ -# Suffix initialization and compiler suffix detection. -# ------------------------------------------------------------------------ - -set(_Boost_VARS_NAME - Boost_NAMESPACE - Boost_COMPILER - Boost_THREADAPI - Boost_USE_DEBUG_PYTHON - Boost_USE_MULTITHREADED - Boost_USE_STATIC_LIBS - Boost_USE_STATIC_RUNTIME - Boost_USE_STLPORT - Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS - ) -_Boost_CHANGE_DETECT(_Boost_CHANGE_LIBNAME ${_Boost_VARS_NAME}) - -# Setting some more suffixes for the library -if (Boost_COMPILER) - set(_boost_COMPILER ${Boost_COMPILER}) - if(Boost_DEBUG) - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "using user-specified Boost_COMPILER = ${_boost_COMPILER}") - endif() -else() - # Attempt to guess the compiler suffix - # NOTE: this is not perfect yet, if you experience any issues - # please report them and use the Boost_COMPILER variable - # to work around the problems. - _Boost_GUESS_COMPILER_PREFIX(_boost_COMPILER) - if(Boost_DEBUG) - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "guessed _boost_COMPILER = ${_boost_COMPILER}") - endif() -endif() - -set (_boost_MULTITHREADED "-mt") -if( NOT Boost_USE_MULTITHREADED ) - set (_boost_MULTITHREADED "") -endif() -if(Boost_DEBUG) - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "_boost_MULTITHREADED = ${_boost_MULTITHREADED}") -endif() - -#====================== -# Systematically build up the Boost ABI tag for the 'tagged' and 'versioned' layouts -# http://boost.org/doc/libs/1_66_0/more/getting_started/windows.html#library-naming -# http://boost.org/doc/libs/1_66_0/boost/config/auto_link.hpp -# http://boost.org/doc/libs/1_66_0/tools/build/src/tools/common.jam -# http://boost.org/doc/libs/1_66_0/boostcpp.jam -set( _boost_RELEASE_ABI_TAG "-") -set( _boost_DEBUG_ABI_TAG "-") -# Key Use this library when: -# s linking statically to the C++ standard library and -# compiler runtime support libraries. -if(Boost_USE_STATIC_RUNTIME) - set( _boost_RELEASE_ABI_TAG "${_boost_RELEASE_ABI_TAG}s") - set( _boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}s") -endif() -# g using debug versions of the standard and runtime -# support libraries -if(WIN32 AND Boost_USE_DEBUG_RUNTIME) - if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" - OR "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xClang" - OR "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xIntel") - string(APPEND _boost_DEBUG_ABI_TAG "g") - endif() -endif() -# y using special debug build of python -if(Boost_USE_DEBUG_PYTHON) - string(APPEND _boost_DEBUG_ABI_TAG "y") -endif() -# d using a debug version of your code -string(APPEND _boost_DEBUG_ABI_TAG "d") -# p using the STLport standard library rather than the -# default one supplied with your compiler -if(Boost_USE_STLPORT) - string(APPEND _boost_RELEASE_ABI_TAG "p") - string(APPEND _boost_DEBUG_ABI_TAG "p") -endif() -# n using the STLport deprecated "native iostreams" feature -# removed from the documentation in 1.43.0 but still present in -# boost/config/auto_link.hpp -if(Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS) - string(APPEND _boost_RELEASE_ABI_TAG "n") - string(APPEND _boost_DEBUG_ABI_TAG "n") -endif() - -# -x86 Architecture and address model tag -# First character is the architecture, then word-size, either 32 or 64 -# Only used in 'versioned' layout, added in Boost 1.66.0 -if(DEFINED Boost_ARCHITECTURE) - set(_boost_ARCHITECTURE_TAG "${Boost_ARCHITECTURE}") - if(Boost_DEBUG) - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "using user-specified Boost_ARCHITECTURE = ${_boost_ARCHITECTURE_TAG}") - endif() -else() - set(_boost_ARCHITECTURE_TAG "") - # {CMAKE_CXX_COMPILER_ARCHITECTURE_ID} is not currently set for all compilers - if(NOT "x${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "x" AND NOT Boost_VERSION VERSION_LESS 106600) - string(APPEND _boost_ARCHITECTURE_TAG "-") - # This needs to be kept in-sync with the section of CMakePlatformId.h.in - # inside 'defined(_WIN32) && defined(_MSC_VER)' - if(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "IA64") - string(APPEND _boost_ARCHITECTURE_TAG "i") - elseif(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "X86" - OR CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "x64") - string(APPEND _boost_ARCHITECTURE_TAG "x") - elseif(CMAKE_CXX_COMPILER_ARCHITECTURE_ID MATCHES "^ARM") - string(APPEND _boost_ARCHITECTURE_TAG "a") - elseif(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "MIPS") - string(APPEND _boost_ARCHITECTURE_TAG "m") - endif() - - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - string(APPEND _boost_ARCHITECTURE_TAG "64") - else() - string(APPEND _boost_ARCHITECTURE_TAG "32") - endif() - endif() -endif() - -if(Boost_DEBUG) - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "_boost_RELEASE_ABI_TAG = ${_boost_RELEASE_ABI_TAG}") - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "_boost_DEBUG_ABI_TAG = ${_boost_DEBUG_ABI_TAG}") -endif() - -# ------------------------------------------------------------------------ -# Begin finding boost libraries -# ------------------------------------------------------------------------ - -set(_Boost_VARS_LIB "") -foreach(c DEBUG RELEASE) - set(_Boost_VARS_LIB_${c} BOOST_LIBRARYDIR Boost_LIBRARY_DIR_${c}) - list(APPEND _Boost_VARS_LIB ${_Boost_VARS_LIB_${c}}) - _Boost_CHANGE_DETECT(_Boost_CHANGE_LIBDIR_${c} ${_Boost_VARS_DIR} ${_Boost_VARS_LIB_${c}} Boost_INCLUDE_DIR) - # Clear Boost_LIBRARY_DIR_${c} if it did not change but other input affecting the - # location did. We will find a new one based on the new inputs. - if(_Boost_CHANGE_LIBDIR_${c} AND NOT _Boost_LIBRARY_DIR_${c}_CHANGED) - unset(Boost_LIBRARY_DIR_${c} CACHE) - endif() - - # If Boost_LIBRARY_DIR_[RELEASE,DEBUG] is set, prefer its value. - if(Boost_LIBRARY_DIR_${c}) - set(_boost_LIBRARY_SEARCH_DIRS_${c} ${Boost_LIBRARY_DIR_${c}} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) - else() - set(_boost_LIBRARY_SEARCH_DIRS_${c} "") - if(BOOST_LIBRARYDIR) - list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${BOOST_LIBRARYDIR}) - elseif(_ENV_BOOST_LIBRARYDIR) - list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${_ENV_BOOST_LIBRARYDIR}) - endif() - - if(BOOST_ROOT) - list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${BOOST_ROOT}/lib ${BOOST_ROOT}/stage/lib) - _Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS(_boost_LIBRARY_SEARCH_DIRS_${c} "${BOOST_ROOT}") - elseif(_ENV_BOOST_ROOT) - list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${_ENV_BOOST_ROOT}/lib ${_ENV_BOOST_ROOT}/stage/lib) - _Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS(_boost_LIBRARY_SEARCH_DIRS_${c} "${_ENV_BOOST_ROOT}") - endif() - - list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} - ${Boost_INCLUDE_DIR}/lib - ${Boost_INCLUDE_DIR}/../lib - ${Boost_INCLUDE_DIR}/stage/lib - ) - _Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS(_boost_LIBRARY_SEARCH_DIRS_${c} "${Boost_INCLUDE_DIR}/..") - _Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS(_boost_LIBRARY_SEARCH_DIRS_${c} "${Boost_INCLUDE_DIR}") - if( Boost_NO_SYSTEM_PATHS ) - list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} NO_CMAKE_SYSTEM_PATH NO_SYSTEM_ENVIRONMENT_PATH) - else() - foreach(ver ${_Boost_KNOWN_VERSIONS}) - string(REPLACE "." "_" ver "${ver}") - _Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS(_boost_LIBRARY_SEARCH_DIRS_${c} "C:/local/boost_${ver}") - endforeach() - _Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS(_boost_LIBRARY_SEARCH_DIRS_${c} "C:/boost") - list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} PATHS - C:/boost/lib - C:/boost - /sw/local/lib - ) - endif() - endif() -endforeach() - -if(Boost_DEBUG) - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "_boost_LIBRARY_SEARCH_DIRS_RELEASE = ${_boost_LIBRARY_SEARCH_DIRS_RELEASE}" - "_boost_LIBRARY_SEARCH_DIRS_DEBUG = ${_boost_LIBRARY_SEARCH_DIRS_DEBUG}") -endif() - -# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES -if( Boost_USE_STATIC_LIBS ) - set( _boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) - if(WIN32) - list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .lib .a) - else() - set(CMAKE_FIND_LIBRARY_SUFFIXES .a) - endif() -endif() - -# We want to use the tag inline below without risking double dashes -if(_boost_RELEASE_ABI_TAG) - if(${_boost_RELEASE_ABI_TAG} STREQUAL "-") - set(_boost_RELEASE_ABI_TAG "") - endif() -endif() -if(_boost_DEBUG_ABI_TAG) - if(${_boost_DEBUG_ABI_TAG} STREQUAL "-") - set(_boost_DEBUG_ABI_TAG "") - endif() -endif() - -# The previous behavior of FindBoost when Boost_USE_STATIC_LIBS was enabled -# on WIN32 was to: -# 1. Search for static libs compiled against a SHARED C++ standard runtime library (use if found) -# 2. Search for static libs compiled against a STATIC C++ standard runtime library (use if found) -# We maintain this behavior since changing it could break people's builds. -# To disable the ambiguous behavior, the user need only -# set Boost_USE_STATIC_RUNTIME either ON or OFF. -set(_boost_STATIC_RUNTIME_WORKAROUND false) -if(WIN32 AND Boost_USE_STATIC_LIBS) - if(NOT DEFINED Boost_USE_STATIC_RUNTIME) - set(_boost_STATIC_RUNTIME_WORKAROUND TRUE) - endif() -endif() - -# On versions < 1.35, remove the System library from the considered list -# since it wasn't added until 1.35. -if(Boost_VERSION AND Boost_FIND_COMPONENTS) - if(Boost_VERSION LESS 103500) - list(REMOVE_ITEM Boost_FIND_COMPONENTS system) - endif() -endif() - -# Additional components may be required via component dependencies. -# Add any missing components to the list. -_Boost_MISSING_DEPENDENCIES(Boost_FIND_COMPONENTS _Boost_EXTRA_FIND_COMPONENTS) - -# If thread is required, get the thread libs as a dependency -if("thread" IN_LIST Boost_FIND_COMPONENTS) - if(Boost_FIND_QUIETLY) - set(_Boost_find_quiet QUIET) - else() - set(_Boost_find_quiet "") - endif() - find_package(Threads ${_Boost_find_quiet}) - unset(_Boost_find_quiet) -endif() - -# If the user changed any of our control inputs flush previous results. -if(_Boost_CHANGE_LIBDIR_DEBUG OR _Boost_CHANGE_LIBDIR_RELEASE OR _Boost_CHANGE_LIBNAME) - foreach(COMPONENT ${_Boost_COMPONENTS_SEARCHED}) - string(TOUPPER ${COMPONENT} UPPERCOMPONENT) - foreach(c DEBUG RELEASE) - set(_var Boost_${UPPERCOMPONENT}_LIBRARY_${c}) - unset(${_var} CACHE) - set(${_var} "${_var}-NOTFOUND") - endforeach() - endforeach() - set(_Boost_COMPONENTS_SEARCHED "") -endif() - -foreach(COMPONENT ${Boost_FIND_COMPONENTS}) - string(TOUPPER ${COMPONENT} UPPERCOMPONENT) - - set( _boost_docstring_release "Boost ${COMPONENT} library (release)") - set( _boost_docstring_debug "Boost ${COMPONENT} library (debug)") - - # Compute component-specific hints. - set(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT "") - if(${COMPONENT} STREQUAL "mpi" OR ${COMPONENT} STREQUAL "mpi_python" OR - ${COMPONENT} STREQUAL "graph_parallel") - foreach(lib ${MPI_CXX_LIBRARIES} ${MPI_C_LIBRARIES}) - if(IS_ABSOLUTE "${lib}") - get_filename_component(libdir "${lib}" PATH) - string(REPLACE "\\" "/" libdir "${libdir}") - list(APPEND _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT ${libdir}) - endif() - endforeach() - endif() - - # Handle Python version suffixes - unset(COMPONENT_PYTHON_VERSION_MAJOR) - unset(COMPONENT_PYTHON_VERSION_MINOR) - if(${COMPONENT} MATCHES "^(python|mpi_python|numpy)([0-9])\$") - set(COMPONENT_UNVERSIONED "${CMAKE_MATCH_1}") - set(COMPONENT_PYTHON_VERSION_MAJOR "${CMAKE_MATCH_2}") - elseif(${COMPONENT} MATCHES "^(python|mpi_python|numpy)([0-9])\\.?([0-9])\$") - set(COMPONENT_UNVERSIONED "${CMAKE_MATCH_1}") - set(COMPONENT_PYTHON_VERSION_MAJOR "${CMAKE_MATCH_2}") - set(COMPONENT_PYTHON_VERSION_MINOR "${CMAKE_MATCH_3}") - endif() - - unset(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME) - if (COMPONENT_PYTHON_VERSION_MINOR) - # Boost >= 1.67 - list(APPEND _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME "${COMPONENT_UNVERSIONED}${COMPONENT_PYTHON_VERSION_MAJOR}${COMPONENT_PYTHON_VERSION_MINOR}") - # Debian/Ubuntu (Some versions omit the 2 and/or 3 from the suffix) - list(APPEND _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME "${COMPONENT_UNVERSIONED}${COMPONENT_PYTHON_VERSION_MAJOR}-py${COMPONENT_PYTHON_VERSION_MAJOR}${COMPONENT_PYTHON_VERSION_MINOR}") - list(APPEND _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME "${COMPONENT_UNVERSIONED}-py${COMPONENT_PYTHON_VERSION_MAJOR}${COMPONENT_PYTHON_VERSION_MINOR}") - # Gentoo - list(APPEND _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME "${COMPONENT_UNVERSIONED}-${COMPONENT_PYTHON_VERSION_MAJOR}${COMPONENT_PYTHON_VERSION_MINOR}") - # RPMs - list(APPEND _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME "${COMPONENT_UNVERSIONED}-${COMPONENT_PYTHON_VERSION_MAJOR}${COMPONENT_PYTHON_VERSION_MINOR}") - endif() - if (COMPONENT_PYTHON_VERSION_MAJOR AND NOT COMPONENT_PYTHON_VERSION_MINOR) - # Boost < 1.67 - list(APPEND _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME "${COMPONENT_UNVERSIONED}${COMPONENT_PYTHON_VERSION_MAJOR}") - endif() - - # Consolidate and report component-specific hints. - if(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME) - list(REMOVE_DUPLICATES _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME) - if(Boost_DEBUG) - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "Component-specific library search names for ${COMPONENT_NAME}: " - "${_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME}") - endif() - endif() - if(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT) - list(REMOVE_DUPLICATES _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT) - if(Boost_DEBUG) - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "Component-specific library search paths for ${COMPONENT}: " - "${_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT}") - endif() - endif() - - # - # Find headers - # - _Boost_COMPONENT_HEADERS("${COMPONENT}" Boost_${UPPERCOMPONENT}_HEADER_NAME) - # Look for a standard boost header file. - if(Boost_${UPPERCOMPONENT}_HEADER_NAME) - if(EXISTS "${Boost_INCLUDE_DIR}/${Boost_${UPPERCOMPONENT}_HEADER_NAME}") - set(Boost_${UPPERCOMPONENT}_HEADER ON) - else() - set(Boost_${UPPERCOMPONENT}_HEADER OFF) - endif() - else() - set(Boost_${UPPERCOMPONENT}_HEADER ON) - message(WARNING "No header defined for ${COMPONENT}; skipping header check") - endif() - - # - # Find RELEASE libraries - # - unset(_boost_RELEASE_NAMES) - foreach(component IN LISTS _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME COMPONENT) - foreach(compiler IN LISTS _boost_COMPILER) - list(APPEND _boost_RELEASE_NAMES - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG} ) - endforeach() - list(APPEND _boost_RELEASE_NAMES - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component} ) - if(_boost_STATIC_RUNTIME_WORKAROUND) - set(_boost_RELEASE_STATIC_ABI_TAG "-s${_boost_RELEASE_ABI_TAG}") - foreach(compiler IN LISTS _boost_COMPILER) - list(APPEND _boost_RELEASE_NAMES - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} ) - endforeach() - list(APPEND _boost_RELEASE_NAMES - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} ) - endif() - endforeach() - if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread") - _Boost_PREPEND_LIST_WITH_THREADAPI(_boost_RELEASE_NAMES ${_boost_RELEASE_NAMES}) - endif() - if(Boost_DEBUG) - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "Searching for ${UPPERCOMPONENT}_LIBRARY_RELEASE: ${_boost_RELEASE_NAMES}") - endif() - - # if Boost_LIBRARY_DIR_RELEASE is not defined, - # but Boost_LIBRARY_DIR_DEBUG is, look there first for RELEASE libs - if(NOT Boost_LIBRARY_DIR_RELEASE AND Boost_LIBRARY_DIR_DEBUG) - list(INSERT _boost_LIBRARY_SEARCH_DIRS_RELEASE 0 ${Boost_LIBRARY_DIR_DEBUG}) - endif() - - # Avoid passing backslashes to _Boost_FIND_LIBRARY due to macro re-parsing. - string(REPLACE "\\" "/" _boost_LIBRARY_SEARCH_DIRS_tmp "${_boost_LIBRARY_SEARCH_DIRS_RELEASE}") - - if(Boost_USE_RELEASE_LIBS) - _Boost_FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE RELEASE - NAMES ${_boost_RELEASE_NAMES} - HINTS ${_boost_LIBRARY_SEARCH_DIRS_tmp} - NAMES_PER_DIR - DOC "${_boost_docstring_release}" - ) - endif() - - # - # Find DEBUG libraries - # - unset(_boost_DEBUG_NAMES) - foreach(component IN LISTS _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME COMPONENT) - foreach(compiler IN LISTS _boost_COMPILER) - list(APPEND _boost_DEBUG_NAMES - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG} ) - endforeach() - list(APPEND _boost_DEBUG_NAMES - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component} ) - if(_boost_STATIC_RUNTIME_WORKAROUND) - set(_boost_DEBUG_STATIC_ABI_TAG "-s${_boost_DEBUG_ABI_TAG}") - foreach(compiler IN LISTS _boost_COMPILER) - list(APPEND _boost_DEBUG_NAMES - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} ) - endforeach() - list(APPEND _boost_DEBUG_NAMES - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} - ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} ) - endif() - endforeach() - if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread") - _Boost_PREPEND_LIST_WITH_THREADAPI(_boost_DEBUG_NAMES ${_boost_DEBUG_NAMES}) - endif() - if(Boost_DEBUG) - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "Searching for ${UPPERCOMPONENT}_LIBRARY_DEBUG: ${_boost_DEBUG_NAMES}") - endif() - - # if Boost_LIBRARY_DIR_DEBUG is not defined, - # but Boost_LIBRARY_DIR_RELEASE is, look there first for DEBUG libs - if(NOT Boost_LIBRARY_DIR_DEBUG AND Boost_LIBRARY_DIR_RELEASE) - list(INSERT _boost_LIBRARY_SEARCH_DIRS_DEBUG 0 ${Boost_LIBRARY_DIR_RELEASE}) - endif() - - # Avoid passing backslashes to _Boost_FIND_LIBRARY due to macro re-parsing. - string(REPLACE "\\" "/" _boost_LIBRARY_SEARCH_DIRS_tmp "${_boost_LIBRARY_SEARCH_DIRS_DEBUG}") - - if(Boost_USE_DEBUG_LIBS) - _Boost_FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG DEBUG - NAMES ${_boost_DEBUG_NAMES} - HINTS ${_boost_LIBRARY_SEARCH_DIRS_tmp} - NAMES_PER_DIR - DOC "${_boost_docstring_debug}" - ) - endif () - - if(Boost_REALPATH) - _Boost_SWAP_WITH_REALPATH(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE "${_boost_docstring_release}") - _Boost_SWAP_WITH_REALPATH(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG "${_boost_docstring_debug}" ) - endif() - - _Boost_ADJUST_LIB_VARS(${UPPERCOMPONENT}) - - # Check if component requires some compiler features - _Boost_COMPILER_FEATURES(${COMPONENT} _Boost_${UPPERCOMPONENT}_COMPILER_FEATURES) - -endforeach() - -# Restore the original find library ordering -if( Boost_USE_STATIC_LIBS ) - set(CMAKE_FIND_LIBRARY_SUFFIXES ${_boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) -endif() - -# ------------------------------------------------------------------------ -# End finding boost libraries -# ------------------------------------------------------------------------ - -set(Boost_INCLUDE_DIRS ${Boost_INCLUDE_DIR}) -set(Boost_LIBRARY_DIRS) -if(Boost_LIBRARY_DIR_RELEASE) - list(APPEND Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIR_RELEASE}) -endif() -if(Boost_LIBRARY_DIR_DEBUG) - list(APPEND Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIR_DEBUG}) -endif() -if(Boost_LIBRARY_DIRS) - list(REMOVE_DUPLICATES Boost_LIBRARY_DIRS) -endif() - -# The above setting of Boost_FOUND was based only on the header files. -# Update it for the requested component libraries. -if(Boost_FOUND) - # The headers were found. Check for requested component libs. - set(_boost_CHECKED_COMPONENT FALSE) - set(_Boost_MISSING_COMPONENTS "") - foreach(COMPONENT ${Boost_FIND_COMPONENTS}) - string(TOUPPER ${COMPONENT} UPPERCOMPONENT) - set(_boost_CHECKED_COMPONENT TRUE) - if(NOT Boost_${UPPERCOMPONENT}_FOUND AND Boost_FIND_REQUIRED_${COMPONENT}) - list(APPEND _Boost_MISSING_COMPONENTS ${COMPONENT}) - endif() - endforeach() - if(_Boost_MISSING_COMPONENTS AND _Boost_EXTRA_FIND_COMPONENTS) - # Optional indirect dependencies are not counted as missing. - list(REMOVE_ITEM _Boost_MISSING_COMPONENTS ${_Boost_EXTRA_FIND_COMPONENTS}) - endif() - - if(Boost_DEBUG) - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] Boost_FOUND = ${Boost_FOUND}") - endif() - - if (_Boost_MISSING_COMPONENTS) - set(Boost_FOUND 0) - # We were unable to find some libraries, so generate a sensible - # error message that lists the libraries we were unable to find. - string(APPEND Boost_ERROR_REASON - "\nCould not find the following") - if(Boost_USE_STATIC_LIBS) - string(APPEND Boost_ERROR_REASON " static") - endif() - string(APPEND Boost_ERROR_REASON - " Boost libraries:\n") - foreach(COMPONENT ${_Boost_MISSING_COMPONENTS}) - string(TOUPPER ${COMPONENT} UPPERCOMPONENT) - string(APPEND Boost_ERROR_REASON - " ${Boost_NAMESPACE}_${COMPONENT}${Boost_ERROR_REASON_${UPPERCOMPONENT}}\n") - endforeach() - - list(LENGTH Boost_FIND_COMPONENTS Boost_NUM_COMPONENTS_WANTED) - list(LENGTH _Boost_MISSING_COMPONENTS Boost_NUM_MISSING_COMPONENTS) - if (${Boost_NUM_COMPONENTS_WANTED} EQUAL ${Boost_NUM_MISSING_COMPONENTS}) - string(APPEND Boost_ERROR_REASON - "No Boost libraries were found. You may need to set BOOST_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT to the location of Boost.") - else () - string(APPEND Boost_ERROR_REASON - "Some (but not all) of the required Boost libraries were found. You may need to install these additional Boost libraries. Alternatively, set BOOST_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT to the location of Boost.") - endif () - endif () - - if( NOT Boost_LIBRARY_DIRS AND NOT _boost_CHECKED_COMPONENT ) - # Compatibility Code for backwards compatibility with CMake - # 2.4's FindBoost module. - - # Look for the boost library path. - # Note that the user may not have installed any libraries - # so it is quite possible the Boost_LIBRARY_DIRS may not exist. - set(_boost_LIB_DIR ${Boost_INCLUDE_DIR}) - - if("${_boost_LIB_DIR}" MATCHES "boost-[0-9]+") - get_filename_component(_boost_LIB_DIR ${_boost_LIB_DIR} PATH) - endif() - - if("${_boost_LIB_DIR}" MATCHES "/include$") - # Strip off the trailing "/include" in the path. - get_filename_component(_boost_LIB_DIR ${_boost_LIB_DIR} PATH) - endif() - - if(EXISTS "${_boost_LIB_DIR}/lib") - string(APPEND _boost_LIB_DIR /lib) - elseif(EXISTS "${_boost_LIB_DIR}/stage/lib") - string(APPEND _boost_LIB_DIR "/stage/lib") - else() - set(_boost_LIB_DIR "") - endif() - - if(_boost_LIB_DIR AND EXISTS "${_boost_LIB_DIR}") - set(Boost_LIBRARY_DIRS ${_boost_LIB_DIR}) - endif() - - endif() -else() - # Boost headers were not found so no components were found. - foreach(COMPONENT ${Boost_FIND_COMPONENTS}) - string(TOUPPER ${COMPONENT} UPPERCOMPONENT) - set(Boost_${UPPERCOMPONENT}_FOUND 0) - endforeach() -endif() - -# ------------------------------------------------------------------------ -# Add imported targets -# ------------------------------------------------------------------------ - -if(Boost_FOUND) - # For header-only libraries - if(NOT TARGET Boost::boost) - add_library(Boost::boost INTERFACE IMPORTED) - if(Boost_INCLUDE_DIRS) - set_target_properties(Boost::boost PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}") - endif() - endif() - - foreach(COMPONENT ${Boost_FIND_COMPONENTS}) - if(_Boost_IMPORTED_TARGETS AND NOT TARGET Boost::${COMPONENT}) - string(TOUPPER ${COMPONENT} UPPERCOMPONENT) - if(Boost_${UPPERCOMPONENT}_FOUND) - if(Boost_USE_STATIC_LIBS) - add_library(Boost::${COMPONENT} STATIC IMPORTED) - else() - # Even if Boost_USE_STATIC_LIBS is OFF, we might have static - # libraries as a result. - add_library(Boost::${COMPONENT} UNKNOWN IMPORTED) - endif() - if(Boost_INCLUDE_DIRS) - set_target_properties(Boost::${COMPONENT} PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}") - endif() - if(EXISTS "${Boost_${UPPERCOMPONENT}_LIBRARY}") - set_target_properties(Boost::${COMPONENT} PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" - IMPORTED_LOCATION "${Boost_${UPPERCOMPONENT}_LIBRARY}") - endif() - if(EXISTS "${Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE}") - set_property(TARGET Boost::${COMPONENT} APPEND PROPERTY - IMPORTED_CONFIGURATIONS RELEASE) - set_target_properties(Boost::${COMPONENT} PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX" - IMPORTED_LOCATION_RELEASE "${Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE}") - endif() - if(EXISTS "${Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG}") - set_property(TARGET Boost::${COMPONENT} APPEND PROPERTY - IMPORTED_CONFIGURATIONS DEBUG) - set_target_properties(Boost::${COMPONENT} PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX" - IMPORTED_LOCATION_DEBUG "${Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG}") - endif() - if(_Boost_${UPPERCOMPONENT}_DEPENDENCIES) - unset(_Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES) - foreach(dep ${_Boost_${UPPERCOMPONENT}_DEPENDENCIES}) - list(APPEND _Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES Boost::${dep}) - endforeach() - if(COMPONENT STREQUAL "thread") - list(APPEND _Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES Threads::Threads) - endif() - set_target_properties(Boost::${COMPONENT} PROPERTIES - INTERFACE_LINK_LIBRARIES "${_Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES}") - endif() - if(_Boost_${UPPERCOMPONENT}_COMPILER_FEATURES) - set_target_properties(Boost::${COMPONENT} PROPERTIES - INTERFACE_COMPILE_FEATURES "${_Boost_${UPPERCOMPONENT}_COMPILER_FEATURES}") - endif() - endif() - endif() - endforeach() -endif() - -# ------------------------------------------------------------------------ -# Notification to end user about what was found -# ------------------------------------------------------------------------ - -set(Boost_LIBRARIES "") -if(Boost_FOUND) - if(NOT Boost_FIND_QUIETLY) - message(STATUS "Boost version: ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}") - if(Boost_FIND_COMPONENTS) - message(STATUS "Found the following Boost libraries:") - endif() - endif() - foreach( COMPONENT ${Boost_FIND_COMPONENTS} ) - string( TOUPPER ${COMPONENT} UPPERCOMPONENT ) - if( Boost_${UPPERCOMPONENT}_FOUND ) - if(NOT Boost_FIND_QUIETLY) - message (STATUS " ${COMPONENT}") - endif() - list(APPEND Boost_LIBRARIES ${Boost_${UPPERCOMPONENT}_LIBRARY}) - if(COMPONENT STREQUAL "thread") - list(APPEND Boost_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) - endif() - endif() - endforeach() -else() - if(Boost_FIND_REQUIRED) - message(SEND_ERROR "Unable to find the requested Boost libraries.\n${Boost_ERROR_REASON}") - else() - if(NOT Boost_FIND_QUIETLY) - # we opt not to automatically output Boost_ERROR_REASON here as - # it could be quite lengthy and somewhat imposing in its requests - # Since Boost is not always a required dependency we'll leave this - # up to the end-user. - if(Boost_DEBUG OR Boost_DETAILED_FAILURE_MSG) - message(STATUS "Could NOT find Boost\n${Boost_ERROR_REASON}") - else() - message(STATUS "Could NOT find Boost") - endif() - endif() - endif() -endif() - -# Configure display of cache entries in GUI. -foreach(v BOOSTROOT BOOST_ROOT ${_Boost_VARS_INC} ${_Boost_VARS_LIB}) - get_property(_type CACHE ${v} PROPERTY TYPE) - if(_type) - set_property(CACHE ${v} PROPERTY ADVANCED 1) - if("x${_type}" STREQUAL "xUNINITIALIZED") - if("x${v}" STREQUAL "xBoost_ADDITIONAL_VERSIONS") - set_property(CACHE ${v} PROPERTY TYPE STRING) - else() - set_property(CACHE ${v} PROPERTY TYPE PATH) - endif() - endif() - endif() -endforeach() - -# Record last used values of input variables so we can -# detect on the next run if the user changed them. -foreach(v - ${_Boost_VARS_INC} ${_Boost_VARS_LIB} - ${_Boost_VARS_DIR} ${_Boost_VARS_NAME} - ) - if(DEFINED ${v}) - set(_${v}_LAST "${${v}}" CACHE INTERNAL "Last used ${v} value.") - else() - unset(_${v}_LAST CACHE) - endif() -endforeach() - -# Maintain a persistent list of components requested anywhere since -# the last flush. -set(_Boost_COMPONENTS_SEARCHED "${_Boost_COMPONENTS_SEARCHED}") -list(APPEND _Boost_COMPONENTS_SEARCHED ${Boost_FIND_COMPONENTS}) -list(REMOVE_DUPLICATES _Boost_COMPONENTS_SEARCHED) -list(SORT _Boost_COMPONENTS_SEARCHED) -set(_Boost_COMPONENTS_SEARCHED "${_Boost_COMPONENTS_SEARCHED}" - CACHE INTERNAL "Components requested for this build tree.") - -# Restore project's policies -cmake_policy(POP) diff --git a/Kommon/cmake/FindCURL.cmake b/Kommon/cmake/FindCURL.cmake new file mode 100644 index 000000000..b1989b10e --- /dev/null +++ b/Kommon/cmake/FindCURL.cmake @@ -0,0 +1,177 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindCURL +-------- + +Find the native CURL headers and libraries. + +This module accept optional COMPONENTS to check supported features and +protocols:: + + PROTOCOLS: ICT FILE FTP FTPS GOPHER HTTP HTTPS IMAP IMAPS LDAP LDAPS POP3 + POP3S RTMP RTSP SCP SFTP SMB SMBS SMTP SMTPS TELNET TFTP + FEATURES: SSL IPv6 UnixSockets libz AsynchDNS IDN GSS-API PSL SPNEGO + Kerberos NTLM NTLM_WB TLS-SRP HTTP2 HTTPS-proxy + +IMPORTED Targets +^^^^^^^^^^^^^^^^ + +This module defines :prop_tgt:`IMPORTED` target ``CURL::libcurl``, if +curl has been found. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module defines the following variables: + +``CURL_FOUND`` + True if curl found. + +``CURL_INCLUDE_DIRS`` + where to find curl/curl.h, etc. + +``CURL_LIBRARIES`` + List of libraries when using curl. + +``CURL_VERSION_STRING`` + The version of curl found. +#]=======================================================================] + +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_check_modules(PC_CURL QUIET libcurl) + if(PC_CURL_FOUND) + set(CURL_VERSION_STRING ${PC_CURL_VERSION}) + pkg_get_variable(CURL_SUPPORTED_PROTOCOLS libcurl supported_protocols) + pkg_get_variable(CURL_SUPPORTED_FEATURES libcurl supported_features) + endif() +endif() + +# Look for the header file. +find_path(CURL_INCLUDE_DIR + NAMES curl/curl.h + HINTS ${PC_CURL_INCLUDE_DIRS}) +mark_as_advanced(CURL_INCLUDE_DIR) + +if(NOT CURL_LIBRARY) + # Look for the library (sorted from most current/relevant entry to least). + find_library(CURL_LIBRARY_RELEASE NAMES + curl + # Windows MSVC prebuilts: + curllib + libcurl_imp + curllib_static + # Windows older "Win32 - MSVC" prebuilts (libcurl.lib, e.g. libcurl-7.15.5-win32-msvc.zip): + libcurl + HINTS ${PC_CURL_LIBRARY_DIRS} + ) + mark_as_advanced(CURL_LIBRARY_RELEASE) + + find_library(CURL_LIBRARY_DEBUG NAMES + # Windows MSVC CMake builds in debug configuration on vcpkg: + libcurl-d_imp + libcurl-d + HINTS ${PC_CURL_LIBRARY_DIRS} + ) + mark_as_advanced(CURL_LIBRARY_DEBUG) + + include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) + select_library_configurations(CURL) +endif() + +if(CURL_INCLUDE_DIR AND NOT CURL_VERSION_STRING) + foreach(_curl_version_header curlver.h curl.h) + if(EXISTS "${CURL_INCLUDE_DIR}/curl/${_curl_version_header}") + file(STRINGS "${CURL_INCLUDE_DIR}/curl/${_curl_version_header}" curl_version_str REGEX "^#define[\t ]+LIBCURL_VERSION[\t ]+\".*\"") + + string(REGEX REPLACE "^#define[\t ]+LIBCURL_VERSION[\t ]+\"([^\"]*)\".*" "\\1" CURL_VERSION_STRING "${curl_version_str}") + unset(curl_version_str) + break() + endif() + endforeach() +endif() + +if(CURL_FIND_COMPONENTS) + set(CURL_KNOWN_PROTOCOLS ICT FILE FTP FTPS GOPHER HTTP HTTPS IMAP IMAPS LDAP LDAPS POP3 POP3S RTMP RTSP SCP SFTP SMB SMBS SMTP SMTPS TELNET TFTP) + set(CURL_KNOWN_FEATURES SSL IPv6 UnixSockets libz AsynchDNS IDN GSS-API PSL SPNEGO Kerberos NTLM NTLM_WB TLS-SRP HTTP2 HTTPS-proxy) + foreach(component IN LISTS CURL_KNOWN_PROTOCOLS CURL_KNOWN_FEATURES) + set(CURL_${component}_FOUND FALSE) + endforeach() + if(NOT PC_CURL_FOUND) + find_program(CURL_CONFIG_EXECUTABLE NAMES curl-config) + if(CURL_CONFIG_EXECUTABLE) + execute_process(COMMAND ${CURL_CONFIG_EXECUTABLE} --version + OUTPUT_VARIABLE CURL_CONFIG_VERSION_STRING + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${CURL_CONFIG_EXECUTABLE} --feature + OUTPUT_VARIABLE CURL_CONFIG_FEATURES_STRING + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REPLACE "\n" ";" CURL_SUPPORTED_FEATURES "${CURL_CONFIG_FEATURES_STRING}") + execute_process(COMMAND ${CURL_CONFIG_EXECUTABLE} --protocols + OUTPUT_VARIABLE CURL_CONFIG_PROTOCOLS_STRING + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REPLACE "\n" ";" CURL_SUPPORTED_PROTOCOLS "${CURL_CONFIG_PROTOCOLS_STRING}") + endif() + + endif() + foreach(component IN LISTS CURL_FIND_COMPONENTS) + list(FIND CURL_KNOWN_PROTOCOLS ${component} _found) + if(_found) + list(FIND CURL_SUPPORTED_PROTOCOLS ${component} _found) + if(_found) + set(CURL_${component}_FOUND TRUE) + elseif(CURL_FIND_REQUIRED) + message(FATAL_ERROR "CURL: Required protocol ${component} is not found") + endif() + else() + list(FIND CURL_SUPPORTED_FEATURES ${component} _found) + if(_found) + set(CURL_${component}_FOUND TRUE) + elseif(CURL_FIND_REQUIRED) + message(FATAL_ERROR "CURL: Required feature ${component} is not found") + endif() + endif() + endforeach() +endif() + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +find_package_handle_standard_args(CURL + REQUIRED_VARS CURL_LIBRARY CURL_INCLUDE_DIR + VERSION_VAR CURL_VERSION_STRING + HANDLE_COMPONENTS) + +if(CURL_FOUND) + set(CURL_LIBRARIES ${CURL_LIBRARY}) + set(CURL_INCLUDE_DIRS ${CURL_INCLUDE_DIR}) + + if(NOT TARGET CURL::libcurl) + add_library(CURL::libcurl UNKNOWN IMPORTED) + set_target_properties(CURL::libcurl PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${CURL_INCLUDE_DIRS}") + + if(EXISTS "${CURL_LIBRARY}") + set_target_properties(CURL::libcurl PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${CURL_LIBRARY}") + endif() + if(CURL_LIBRARY_RELEASE) + set_property(TARGET CURL::libcurl APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(CURL::libcurl PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION_RELEASE "${CURL_LIBRARY_RELEASE}") + endif() + if(CURL_LIBRARY_DEBUG) + set_property(TARGET CURL::libcurl APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(CURL::libcurl PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION_DEBUG "${CURL_LIBRARY_DEBUG}") + endif() + endif() +endif() diff --git a/Kommon/cmake/FindDoxygen.cmake b/Kommon/cmake/FindDoxygen.cmake new file mode 100644 index 000000000..32b4aa2c8 --- /dev/null +++ b/Kommon/cmake/FindDoxygen.cmake @@ -0,0 +1,1122 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindDoxygen +----------- + +Doxygen is a documentation generation tool (see http://www.doxygen.org). +This module looks for Doxygen and some optional tools it supports. These +tools are enabled as components in the :command:`find_package` command: + +``dot`` + `Graphviz `_ ``dot`` utility used to render various + graphs. +``mscgen`` + `Message Chart Generator `_ utility used + by Doxygen's ``\msc`` and ``\mscfile`` commands. +``dia`` + `Dia `_ the diagram editor used by Doxygen's + ``\diafile`` command. + +Examples: + +.. code-block:: cmake + + # Require dot, treat the other components as optional + find_package(Doxygen + REQUIRED dot + OPTIONAL_COMPONENTS mscgen dia) + +The following variables are defined by this module: + +.. variable:: DOXYGEN_FOUND + + True if the ``doxygen`` executable was found. + +.. variable:: DOXYGEN_VERSION + + The version reported by ``doxygen --version``. + +The module defines ``IMPORTED`` targets for Doxygen and each component found. +These can be used as part of custom commands, etc. and should be preferred over +old-style (and now deprecated) variables like ``DOXYGEN_EXECUTABLE``. The +following import targets are defined if their corresponding executable could be +found (the component import targets will only be defined if that component was +requested): + +:: + + Doxygen::doxygen + Doxygen::dot + Doxygen::mscgen + Doxygen::dia + + +Functions +^^^^^^^^^ + +.. command:: doxygen_add_docs + + This function is intended as a convenience for adding a target for generating + documentation with Doxygen. It aims to provide sensible defaults so that + projects can generally just provide the input files and directories and that + will be sufficient to give sensible results. The function supports the + ability to customize the Doxygen configuration used to build the + documentation. + + :: + + doxygen_add_docs(targetName + [filesOrDirs...] + [ALL] + [WORKING_DIRECTORY dir] + [COMMENT comment]) + + The function constructs a ``Doxyfile`` and defines a custom target that runs + Doxygen on that generated file. The listed files and directories are used as + the ``INPUT`` of the generated ``Doxyfile`` and they can contain wildcards. + Any files that are listed explicitly will also be added as ``SOURCES`` of the + custom target so they will show up in an IDE project's source list. + + So that relative input paths work as expected, by default the working + directory of the Doxygen command will be the current source directory (i.e. + :variable:`CMAKE_CURRENT_SOURCE_DIR`). This can be overridden with the + ``WORKING_DIRECTORY`` option to change the directory used as the relative + base point. Note also that Doxygen's default behavior is to strip the working + directory from relative paths in the generated documentation (see the + ``STRIP_FROM_PATH`` `Doxygen config option + `_ for details). + + If provided, the optional ``comment`` will be passed as the ``COMMENT`` for + the :command:`add_custom_target` command used to create the custom target + internally. + + If ALL is set, the target will be added to the default build target. + + The contents of the generated ``Doxyfile`` can be customized by setting CMake + variables before calling ``doxygen_add_docs()``. Any variable with a name of + the form ``DOXYGEN_`` will have its value substituted for the + corresponding ```` configuration option in the ``Doxyfile``. See the + `Doxygen documentation `_ for the + full list of supported configuration options. + + Some of Doxygen's defaults are overridden to provide more appropriate + behavior for a CMake project. Each of the following will be explicitly set + unless the variable already has a value before ``doxygen_add_docs()`` is + called (with some exceptions noted): + + .. variable:: DOXYGEN_HAVE_DOT + + Set to ``YES`` if the ``dot`` component was requested and it was found, + ``NO`` otherwise. Any existing value of ``DOXYGEN_HAVE_DOT`` is ignored. + + .. variable:: DOXYGEN_DOT_MULTI_TARGETS + + Set to ``YES`` by this module (note that this requires a ``dot`` version + newer than 1.8.10). This option is only meaningful if ``DOXYGEN_HAVE_DOT`` + is also set to ``YES``. + + .. variable:: DOXYGEN_GENERATE_LATEX + + Set to ``NO`` by this module. + + .. variable:: DOXYGEN_WARN_FORMAT + + For Visual Studio based generators, this is set to the form recognized by + the Visual Studio IDE: ``$file($line) : $text``. For all other generators, + Doxygen's default value is not overridden. + + .. variable:: DOXYGEN_PROJECT_NAME + + Populated with the name of the current project (i.e. + :variable:`PROJECT_NAME`). + + .. variable:: DOXYGEN_PROJECT_NUMBER + + Populated with the version of the current project (i.e. + :variable:`PROJECT_VERSION`). + + .. variable:: DOXYGEN_PROJECT_BRIEF + + Populated with the description of the current project (i.e. + :variable:`PROJECT_DESCRIPTION`). + + .. variable:: DOXYGEN_INPUT + + Projects should not set this variable. It will be populated with the set of + files and directories passed to ``doxygen_add_docs()``, thereby providing + consistent behavior with the other built-in commands like + :command:`add_executable`, :command:`add_library` and + :command:`add_custom_target`. If a variable named ``DOXYGEN_INPUT`` is set + by the project, it will be ignored and a warning will be issued. + + .. variable:: DOXYGEN_RECURSIVE + + Set to ``YES`` by this module. + + .. variable:: DOXYGEN_EXCLUDE_PATTERNS + + If the set of inputs includes directories, this variable will specify + patterns used to exclude files from them. The following patterns are added + by ``doxygen_add_docs()`` to ensure CMake-specific files and directories + are not included in the input. If the project sets + ``DOXYGEN_EXCLUDE_PATTERNS``, those contents are merged with these + additional patterns rather than replacing them: + + :: + + */.git/* + */.svn/* + */.hg/* + */CMakeFiles/* + */_CPack_Packages/* + DartConfiguration.tcl + CMakeLists.txt + CMakeCache.txt + + .. variable:: DOXYGEN_OUTPUT_DIRECTORY + + Set to :variable:`CMAKE_CURRENT_BINARY_DIR` by this module. Note that if + the project provides its own value for this and it is a relative path, it + will be converted to an absolute path relative to the current binary + directory. This is necessary because doxygen will normally be run from a + directory within the source tree so that relative source paths work as + expected. If this directory does not exist, it will be recursively created + prior to executing the doxygen commands. + +To change any of these defaults or override any other Doxygen config option, +set relevant variables before calling ``doxygen_add_docs()``. For example: + + .. code-block:: cmake + + set(DOXYGEN_GENERATE_HTML NO) + set(DOXYGEN_GENERATE_MAN YES) + + doxygen_add_docs( + doxygen + ${PROJECT_SOURCE_DIR} + COMMENT "Generate man pages" + ) + +A number of Doxygen config options accept lists of values, but Doxygen requires +them to be separated by whitespace. CMake variables hold lists as a string with +items separated by semi-colons, so a conversion needs to be performed. The +``doxygen_add_docs()`` command specifically checks the following Doxygen config +options and will convert their associated CMake variable's contents into the +required form if set. + +:: + + ABBREVIATE_BRIEF + ALIASES + CITE_BIB_FILES + DIAFILE_DIRS + DOTFILE_DIRS + DOT_FONTPATH + ENABLED_SECTIONS + EXAMPLE_PATH + EXAMPLE_PATTERNS + EXCLUDE + EXCLUDE_PATTERNS + EXCLUDE_SYMBOLS + EXPAND_AS_DEFINED + EXTENSION_MAPPING + EXTRA_PACKAGES + EXTRA_SEARCH_MAPPINGS + FILE_PATTERNS + FILTER_PATTERNS + FILTER_SOURCE_PATTERNS + HTML_EXTRA_FILES + HTML_EXTRA_STYLESHEET + IGNORE_PREFIX + IMAGE_PATH + INCLUDE_FILE_PATTERNS + INCLUDE_PATH + INPUT + LATEX_EXTRA_FILES + LATEX_EXTRA_STYLESHEET + MATHJAX_EXTENSIONS + MSCFILE_DIRS + PLANTUML_INCLUDE_PATH + PREDEFINED + QHP_CUST_FILTER_ATTRS + QHP_SECT_FILTER_ATTRS + STRIP_FROM_INC_PATH + STRIP_FROM_PATH + TAGFILES + TCL_SUBST + +The following single value Doxygen options will be quoted automatically +if they contain at least one space: + +:: + + CHM_FILE + DIA_PATH + DOCBOOK_OUTPUT + DOCSET_FEEDNAME + DOCSET_PUBLISHER_NAME + DOT_FONTNAME + DOT_PATH + EXTERNAL_SEARCH_ID + FILE_VERSION_FILTER + GENERATE_TAGFILE + HHC_LOCATION + HTML_FOOTER + HTML_HEADER + HTML_OUTPUT + HTML_STYLESHEET + INPUT_FILTER + LATEX_FOOTER + LATEX_HEADER + LATEX_OUTPUT + LAYOUT_FILE + MAN_OUTPUT + MAN_SUBDIR + MATHJAX_CODEFILE + MSCGEN_PATH + OUTPUT_DIRECTORY + PERL_PATH + PLANTUML_JAR_PATH + PROJECT_BRIEF + PROJECT_LOGO + PROJECT_NAME + QCH_FILE + QHG_LOCATION + QHP_CUST_FILTER_NAME + QHP_VIRTUAL_FOLDER + RTF_EXTENSIONS_FILE + RTF_OUTPUT + RTF_STYLESHEET_FILE + SEARCHDATA_FILE + USE_MDFILE_AS_MAINPAGE + WARN_FORMAT + WARN_LOGFILE + XML_OUTPUT + +There are situations where it may be undesirable for a particular config option +to be automatically quoted by ``doxygen_add_docs()``, such as ``ALIASES`` which +may need to include its own embedded quoting. The ``DOXYGEN_VERBATIM_VARS`` +variable can be used to specify a list of Doxygen variables (including the +leading ``DOXYGEN_`` prefix) which should not be quoted. The project is then +responsible for ensuring that those variables' values make sense when placed +directly in the Doxygen input file. In the case of list variables, list items +are still separated by spaces, it is only the automatic quoting that is +skipped. For example, the following allows ``doxygen_add_docs()`` to apply +quoting to ``DOXYGEN_PROJECT_BRIEF``, but not each item in the +``DOXYGEN_ALIASES`` list (:ref:`bracket syntax ` can also +be used to make working with embedded quotes easier): + +.. code-block:: cmake + + set(DOXYGEN_PROJECT_BRIEF "String with spaces") + set(DOXYGEN_ALIASES + [[somealias="@some_command param"]] + "anotherAlias=@foobar" + ) + set(DOXYGEN_VERBATIM_VARS DOXYGEN_ALIASES) + +The resultant ``Doxyfile`` will contain the following lines: + +.. code-block:: text + + PROJECT_BRIEF = "String with spaces" + ALIASES = somealias="@some_command param" anotherAlias=@foobar + + +Deprecated Result Variables +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For compatibility with previous versions of CMake, the following variables +are also defined but they are deprecated and should no longer be used: + +.. variable:: DOXYGEN_EXECUTABLE + + The path to the ``doxygen`` command. If projects need to refer to the + ``doxygen`` executable directly, they should use the ``Doxygen::doxygen`` + import target instead. + +.. variable:: DOXYGEN_DOT_FOUND + + True if the ``dot`` executable was found. + +.. variable:: DOXYGEN_DOT_EXECUTABLE + + The path to the ``dot`` command. If projects need to refer to the ``dot`` + executable directly, they should use the ``Doxygen::dot`` import target + instead. + +.. variable:: DOXYGEN_DOT_PATH + + The path to the directory containing the ``dot`` executable as reported in + ``DOXYGEN_DOT_EXECUTABLE``. The path may have forward slashes even on Windows + and is not suitable for direct substitution into a ``Doxyfile.in`` template. + If you need this value, get the :prop_tgt:`IMPORTED_LOCATION` property of the + ``Doxygen::dot`` target and use :command:`get_filename_component` to extract + the directory part of that path. You may also want to consider using + :command:`file(TO_NATIVE_PATH)` to prepare the path for a Doxygen + configuration file. + + +Deprecated Hint Variables +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. variable:: DOXYGEN_SKIP_DOT + + This variable has no effect for the component form of ``find_package``. + In backward compatibility mode (i.e. without components list) it prevents + the finder module from searching for Graphviz's ``dot`` utility. + +#]=======================================================================] + +cmake_policy(PUSH) +cmake_policy(SET CMP0057 NEW) # if IN_LIST + +# For backwards compatibility support +if(Doxygen_FIND_QUIETLY) + set(DOXYGEN_FIND_QUIETLY TRUE) +endif() + +# ===== Rationale for OS X AppBundle mods below ===== +# With the OS X GUI version, Doxygen likes to be installed to /Applications +# and it contains the doxygen executable in the bundle. In the versions I've +# seen, it is located in Resources, but in general, more often binaries are +# located in MacOS. +# +# NOTE: The official Doxygen.app distributed for OS X uses non-standard +# conventions. Instead of the command-line "doxygen" tool being placed in +# Doxygen.app/Contents/MacOS, "Doxywizard" is placed there instead and +# "doxygen" is placed in Contents/Resources. This is most likely done +# so that something happens when people double-click on the Doxygen.app +# package. Unfortunately, CMake gets confused by this as when it sees the +# bundle it uses "Doxywizard" as the executable to use instead of +# "doxygen". Therefore to work-around this issue we temporarily disable +# the app-bundle feature, just for this CMake module: +# +if(APPLE) + # Save the old setting + set(TEMP_DOXYGEN_SAVE_CMAKE_FIND_APPBUNDLE ${CMAKE_FIND_APPBUNDLE}) + # Disable the App-bundle detection feature + set(CMAKE_FIND_APPBUNDLE "NEVER") +endif() +# FYI: +# In older versions of OS X Doxygen, dot was included with the Doxygen bundle, +# but newer versions require you to download Graphviz.app which contains "dot" +# or use something like homebrew. +# ============== End OSX stuff ================ + +# +# Find Doxygen... +# +macro(_Doxygen_find_doxygen) + find_program( + DOXYGEN_EXECUTABLE + NAMES doxygen + PATHS + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\doxygen_is1;Inno Setup: App Path]/bin" + /Applications/Doxygen.app/Contents/Resources + /Applications/Doxygen.app/Contents/MacOS + /Applications/Utilities/Doxygen.app/Contents/Resources + /Applications/Utilities/Doxygen.app/Contents/MacOS + DOC "Doxygen documentation generation tool (http://www.doxygen.org)" + ) + mark_as_advanced(DOXYGEN_EXECUTABLE) + + if(DOXYGEN_EXECUTABLE) + execute_process( + COMMAND "${DOXYGEN_EXECUTABLE}" --version + OUTPUT_VARIABLE DOXYGEN_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE _Doxygen_version_result + ) + if(_Doxygen_version_result) + message(WARNING "Unable to determine doxygen version: ${_Doxygen_version_result}") + endif() + + # Create an imported target for Doxygen + if(NOT TARGET Doxygen::doxygen) + add_executable(Doxygen::doxygen IMPORTED GLOBAL) + set_target_properties(Doxygen::doxygen PROPERTIES + IMPORTED_LOCATION "${DOXYGEN_EXECUTABLE}" + ) + endif() + endif() +endmacro() + +# +# Find Diagram Editor... +# +macro(_Doxygen_find_dia) + set(_x86 "(x86)") + find_program( + DOXYGEN_DIA_EXECUTABLE + NAMES dia + PATHS + "$ENV{ProgramFiles}/Dia" + "$ENV{ProgramFiles${_x86}}/Dia" + DOC "Diagram Editor tool for use with Doxygen" + ) + mark_as_advanced(DOXYGEN_DIA_EXECUTABLE) + + if(DOXYGEN_DIA_EXECUTABLE) + # The Doxyfile wants the path to the utility, not the entire path + # including file name + get_filename_component(DOXYGEN_DIA_PATH + "${DOXYGEN_DIA_EXECUTABLE}" + DIRECTORY) + if(WIN32) + file(TO_NATIVE_PATH "${DOXYGEN_DIA_PATH}" DOXYGEN_DIA_PATH) + endif() + + # Create an imported target for component + if(NOT TARGET Doxygen::dia) + add_executable(Doxygen::dia IMPORTED GLOBAL) + set_target_properties(Doxygen::dia PROPERTIES + IMPORTED_LOCATION "${DOXYGEN_DIA_EXECUTABLE}" + ) + endif() + endif() + + unset(_x86) +endmacro() + +# +# Find Graphviz Dot... +# +macro(_Doxygen_find_dot) + if(WIN32) + set(_x86 "(x86)") + file( + GLOB _Doxygen_GRAPHVIZ_BIN_DIRS + "$ENV{ProgramFiles}/Graphviz*/bin" + "$ENV{ProgramFiles${_x86}}/Graphviz*/bin" + ) + unset(_x86) + else() + set(_Doxygen_GRAPHVIZ_BIN_DIRS "") + endif() + + find_program( + DOXYGEN_DOT_EXECUTABLE + NAMES dot + PATHS + ${_Doxygen_GRAPHVIZ_BIN_DIRS} + "$ENV{ProgramFiles}/ATT/Graphviz/bin" + "C:/Program Files/ATT/Graphviz/bin" + [HKEY_LOCAL_MACHINE\\SOFTWARE\\ATT\\Graphviz;InstallPath]/bin + /Applications/Graphviz.app/Contents/MacOS + /Applications/Utilities/Graphviz.app/Contents/MacOS + /Applications/Doxygen.app/Contents/Resources + /Applications/Doxygen.app/Contents/MacOS + /Applications/Utilities/Doxygen.app/Contents/Resources + /Applications/Utilities/Doxygen.app/Contents/MacOS + DOC "Dot tool for use with Doxygen" + ) + mark_as_advanced(DOXYGEN_DOT_EXECUTABLE) + + if(DOXYGEN_DOT_EXECUTABLE) + # The Doxyfile wants the path to the utility, not the entire path + # including file name + get_filename_component(DOXYGEN_DOT_PATH + "${DOXYGEN_DOT_EXECUTABLE}" + DIRECTORY) + if(WIN32) + file(TO_NATIVE_PATH "${DOXYGEN_DOT_PATH}" DOXYGEN_DOT_PATH) + endif() + + # Create an imported target for component + if(NOT TARGET Doxygen::dot) + add_executable(Doxygen::dot IMPORTED GLOBAL) + set_target_properties(Doxygen::dot PROPERTIES + IMPORTED_LOCATION "${DOXYGEN_DOT_EXECUTABLE}" + ) + endif() + endif() + + unset(_Doxygen_GRAPHVIZ_BIN_DIRS) +endmacro() + +# +# Find Message Sequence Chart... +# +macro(_Doxygen_find_mscgen) + set(_x86 "(x86)") + find_program( + DOXYGEN_MSCGEN_EXECUTABLE + NAMES mscgen + PATHS + "$ENV{ProgramFiles}/Mscgen" + "$ENV{ProgramFiles${_x86}}/Mscgen" + DOC "Message sequence chart tool for use with Doxygen" + ) + mark_as_advanced(DOXYGEN_MSCGEN_EXECUTABLE) + + if(DOXYGEN_MSCGEN_EXECUTABLE) + # The Doxyfile wants the path to the utility, not the entire path + # including file name + get_filename_component(DOXYGEN_MSCGEN_PATH + "${DOXYGEN_MSCGEN_EXECUTABLE}" + DIRECTORY) + if(WIN32) + file(TO_NATIVE_PATH "${DOXYGEN_MSCGEN_PATH}" DOXYGEN_MSCGEN_PATH) + endif() + + # Create an imported target for component + if(NOT TARGET Doxygen::mscgen) + add_executable(Doxygen::mscgen IMPORTED GLOBAL) + set_target_properties(Doxygen::mscgen PROPERTIES + IMPORTED_LOCATION "${DOXYGEN_MSCGEN_EXECUTABLE}" + ) + endif() + endif() + + unset(_x86) +endmacro() + +# Make sure `doxygen` is one of the components to find +set(_Doxygen_keep_backward_compat FALSE) +if(NOT Doxygen_FIND_COMPONENTS) + # Search at least for `doxygen` executable + set(Doxygen_FIND_COMPONENTS doxygen) + # Preserve backward compatibility: + # search for `dot` also if `DOXYGEN_SKIP_DOT` is not explicitly disable this. + if(NOT DOXYGEN_SKIP_DOT) + list(APPEND Doxygen_FIND_COMPONENTS dot) + endif() + set(_Doxygen_keep_backward_compat TRUE) +elseif(NOT doxygen IN_LIST Doxygen_FIND_COMPONENTS) + list(INSERT Doxygen_FIND_COMPONENTS 0 doxygen) +endif() + +# +# Find all requested components of Doxygen... +# +foreach(_comp IN LISTS Doxygen_FIND_COMPONENTS) + if(_comp STREQUAL "doxygen") + _Doxygen_find_doxygen() + elseif(_comp STREQUAL "dia") + _Doxygen_find_dia() + elseif(_comp STREQUAL "dot") + _Doxygen_find_dot() + elseif(_comp STREQUAL "mscgen") + _Doxygen_find_mscgen() + else() + message(WARNING "${_comp} is not a valid Doxygen component") + set(Doxygen_${_comp}_FOUND FALSE) + continue() + endif() + + if(TARGET Doxygen::${_comp}) + set(Doxygen_${_comp}_FOUND TRUE) + else() + set(Doxygen_${_comp}_FOUND FALSE) + endif() +endforeach() +unset(_comp) + +# Verify find results +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +find_package_handle_standard_args( + Doxygen + REQUIRED_VARS DOXYGEN_EXECUTABLE + VERSION_VAR DOXYGEN_VERSION + HANDLE_COMPONENTS +) + +# +# Backwards compatibility... +# +if(APPLE) + # Restore the old app-bundle setting + set(CMAKE_FIND_APPBUNDLE ${TEMP_DOXYGEN_SAVE_CMAKE_FIND_APPBUNDLE}) +endif() + +# Maintain the _FOUND variables as "YES" or "NO" for backwards +# compatibility. This allows people to substitute them directly into +# Doxyfile with configure_file(). +if(DOXYGEN_FOUND) + set(DOXYGEN_FOUND "YES") +else() + set(DOXYGEN_FOUND "NO") +endif() +if(_Doxygen_keep_backward_compat) + if(Doxygen_dot_FOUND) + set(DOXYGEN_DOT_FOUND "YES") + else() + set(DOXYGEN_DOT_FOUND "NO") + endif() + + # For backwards compatibility support for even older CMake versions + set(DOXYGEN ${DOXYGEN_EXECUTABLE}) + set(DOT ${DOXYGEN_DOT_EXECUTABLE}) + + # No need to keep any backward compatibility for `DOXYGEN_MSCGEN_XXX` + # and `DOXYGEN_DIA_XXX` since they were not supported before component + # support was added +endif() +unset(_Doxygen_keep_backward_compat) + +# +# Allow full control of Doxygen from CMakeLists.txt +# + +# Prepare a template Doxyfile and Doxygen's default values CMake file +if(TARGET Doxygen::doxygen) + # If doxygen was found, use it to generate a minimal default Doxyfile. + # We will delete this file after we have finished using it below to + # generate the other files that doxygen_add_docs() will use. + set(_Doxygen_tpl "${CMAKE_BINARY_DIR}/CMakeDoxyfile.tpl") + execute_process( + COMMAND "${DOXYGEN_EXECUTABLE}" -s -g "${_Doxygen_tpl}" + OUTPUT_QUIET + RESULT_VARIABLE _Doxygen_tpl_result + ) + if(_Doxygen_tpl_result) + message(FATAL_ERROR + "Unable to generate Doxyfile template: ${_Doxygen_tpl_result}") + elseif(NOT EXISTS "${_Doxygen_tpl}") + message(FATAL_ERROR + "Doxygen has failed to generate a Doxyfile template") + endif() + + # Write a do-not-edit header to files we are going to generate... + set(_Doxygen_dne_header +[[ +# +# DO NOT EDIT! THIS FILE WAS GENERATED BY CMAKE! +# + +]] + ) + # We only need one copy of these across the whole build, since their + # content is only dependent on the version of Doxygen being used. Therefore + # we always put them at the top of the build tree so that they are in a + # predictable location. + set(_doxyfile_in "${CMAKE_BINARY_DIR}/CMakeDoxyfile.in") + set(_doxyfile_defaults "${CMAKE_BINARY_DIR}/CMakeDoxygenDefaults.cmake") + + file(WRITE "${_doxyfile_in}" ${_Doxygen_dne_header}) + file(WRITE "${_doxyfile_defaults}" ${_Doxygen_dne_header}) + + # Get strings containing a configuration key from the template Doxyfile + # we obtained from this version of Doxygen. Because some options are split + # across multiple lines by ending lines with backslashes, we cannot just + # use file(STRINGS...) with a REGEX. Instead, read lines without a REGEX + # so that file(STRINGS...) handles the trailing backslash as a line + # continuation. It stores multi-lines as lists, so we then have to replace + # the ";" list separator with backslashed newlines again so that we get the + # original content stored back as the value part. + file(STRINGS "${_Doxygen_tpl}" _file_lines) + unset(_Doxygen_tpl_params) + foreach(_line IN LISTS _file_lines) + if(_line MATCHES "([A-Z][A-Z0-9_]+)( *=)(.*)") + set(_key "${CMAKE_MATCH_1}") + set(_eql "${CMAKE_MATCH_2}") + set(_value "${CMAKE_MATCH_3}") + string(REPLACE "\\" "\\\\" _value "${_value}") + string(REPLACE ";" "\\\n" _value "${_value}") + list(APPEND _Doxygen_tpl_params "${_key}${_eql}${_value}") + endif() + endforeach() + + # Build up a Doxyfile that provides @configVar@ substitutions for each + # Doxygen config option as well as a separate CMake script which provides + # the default value for each of those options if the project doesn't supply + # them. Each config option will support substitution of a CMake variable + # of the same name except with DOXYGEN_ prepended. + foreach(_Doxygen_param IN LISTS _Doxygen_tpl_params) + if(_Doxygen_param MATCHES "([A-Z][A-Z0-9_]+)( *)=( (.*))?") + # Ok, this is a config key with a value + if(CMAKE_MATCH_COUNT EQUAL 4) + file(APPEND "${_doxyfile_in}" + "${CMAKE_MATCH_1}${CMAKE_MATCH_2}= @DOXYGEN_${CMAKE_MATCH_1}@\n") + # Remove the backslashes we had to preserve to handle newlines + string(REPLACE "\\\n" "\n" _value "${CMAKE_MATCH_4}") + file(APPEND "${_doxyfile_defaults}" +"if(NOT DEFINED DOXYGEN_${CMAKE_MATCH_1}) + set(DOXYGEN_${CMAKE_MATCH_1} ${_value}) +endif() +") + # Ok, this is a config key with empty default value + elseif(CMAKE_MATCH_COUNT EQUAL 2) + file(APPEND "${_doxyfile_in}" + "${CMAKE_MATCH_1}${CMAKE_MATCH_2}= @DOXYGEN_${CMAKE_MATCH_1}@\n") + else() + message(AUTHOR_WARNING +"Unexpected line format! Code review required!\nFault line: ${_Doxygen_param}") + endif() + else() + message(AUTHOR_WARNING +"Unexpected line format! Code review required!\nFault line: ${_Doxygen_param}") + endif() + endforeach() + + # Ok, dumped defaults are not needed anymore... + file(REMOVE "${_Doxygen_tpl}") + + unset(_Doxygen_param) + unset(_Doxygen_tpl_params) + unset(_Doxygen_dne_header) + unset(_Doxygen_tpl) + +endif() + +function(doxygen_quote_value VARIABLE) + # Quote a value of the given variable if: + # - VARIABLE parameter was really given + # - the variable it names is defined and is not present in the list + # specified by DOXYGEN_VERBATIM_VARS (if set) + # - the value of the named variable isn't already quoted + # - the value has spaces + if(VARIABLE AND DEFINED ${VARIABLE} AND + NOT ${VARIABLE} MATCHES "^\".* .*\"$" AND ${VARIABLE} MATCHES " " AND + NOT (DEFINED DOXYGEN_VERBATIM_VARS AND + "${VARIABLE}" IN_LIST DOXYGEN_VERBATIM_VARS)) + set(${VARIABLE} "\"${${VARIABLE}}\"" PARENT_SCOPE) + endif() +endfunction() + +function(doxygen_list_to_quoted_strings LIST_VARIABLE) + if(LIST_VARIABLE AND DEFINED ${LIST_VARIABLE}) + unset(_inputs) + unset(_sep) + unset(_verbatim) + # Have to test if list items should be treated as verbatim here + # because we lose the variable name when we pass just one list item + # to doxygen_quote_value() below + if(DEFINED DOXYGEN_VERBATIM_VARS AND + "${LIST_VARIABLE}" IN_LIST DOXYGEN_VERBATIM_VARS) + set(_verbatim True) + endif() + foreach(_in IN LISTS ${LIST_VARIABLE}) + if(NOT _verbatim) + doxygen_quote_value(_in) + endif() + string(APPEND _inputs "${_sep}${_in}") + set(_sep " ") + endforeach() + set(${LIST_VARIABLE} "${_inputs}" PARENT_SCOPE) + endif() +endfunction() + +function(doxygen_add_docs targetName) + set(_options ALL) + set(_one_value_args WORKING_DIRECTORY COMMENT) + set(_multi_value_args) + cmake_parse_arguments(_args + "${_options}" + "${_one_value_args}" + "${_multi_value_args}" + ${ARGN}) + + if(NOT _args_COMMENT) + set(_args_COMMENT "Generate API documentation for ${targetName}") + endif() + + if(NOT _args_WORKING_DIRECTORY) + set(_args_WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") + endif() + + if(DEFINED DOXYGEN_INPUT) + message(WARNING +"DOXYGEN_INPUT is set but it will be ignored. Pass the files and directories \ +directly to the doxygen_add_docs() command instead.") + endif() + set(DOXYGEN_INPUT ${_args_UNPARSED_ARGUMENTS}) + + if(NOT TARGET Doxygen::doxygen) + message(FATAL_ERROR "Doxygen was not found, needed by \ +doxygen_add_docs() for target ${targetName}") + endif() + + # If not already defined, set some relevant defaults based on the + # assumption that the documentation is for the whole project. Details + # specified in the project() command will be used to populate a number of + # these defaults. + + if(NOT DEFINED DOXYGEN_PROJECT_NAME) + # The PROJECT_NAME tag is a single word (or a sequence of words + # surrounded by double-quotes, unless you are using Doxywizard) that + # should identify the project for which the documentation is generated. + # This name is used in the title of most generated pages and in a few + # other places. The default value is: My Project. + set(DOXYGEN_PROJECT_NAME ${PROJECT_NAME}) + endif() + + if(NOT DEFINED DOXYGEN_PROJECT_NUMBER) + # The PROJECT_NUMBER tag can be used to enter a project or revision + # number. This could be handy for archiving the generated documentation + # or if some version control system is used. + set(DOXYGEN_PROJECT_NUMBER ${PROJECT_VERSION}) + endif() + + if(NOT DEFINED DOXYGEN_PROJECT_BRIEF) + # Using the PROJECT_BRIEF tag one can provide an optional one line + # description for a project that appears at the top of each page and + # should give viewer a quick idea about the purpose of the project. + # Keep the description short. + set(DOXYGEN_PROJECT_BRIEF "${PROJECT_DESCRIPTION}") + endif() + + if(NOT DEFINED DOXYGEN_RECURSIVE) + # The RECURSIVE tag can be used to specify whether or not + # subdirectories should be searched for input files as well. CMake + # projects generally evolve to span multiple directories, so it makes + # more sense for this to be on by default. Doxygen's default value + # has this setting turned off, so we override it. + set(DOXYGEN_RECURSIVE YES) + endif() + + if(NOT DEFINED DOXYGEN_OUTPUT_DIRECTORY) + # The OUTPUT_DIRECTORY tag is used to specify the (relative or + # absolute) path into which the generated documentation will be + # written. If a relative path is used, Doxygen will interpret it as + # being relative to the location where doxygen was started, but we need + # to run Doxygen in the source tree so that relative input paths work + # intuitively. Therefore, we ensure that the output directory is always + # an absolute path and if the project provided a relative path, we + # treat it as relative to the current BINARY directory so that output + # is not generated inside the source tree. + set(DOXYGEN_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + elseif(NOT IS_ABSOLUTE "${DOXYGEN_OUTPUT_DIRECTORY}") + get_filename_component(DOXYGEN_OUTPUT_DIRECTORY + "${DOXYGEN_OUTPUT_DIRECTORY}" + ABSOLUTE + BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}") + endif() + + if(NOT DEFINED DOXYGEN_HAVE_DOT) + # If you set the HAVE_DOT tag to YES then doxygen will assume the dot + # tool is available from the path. This tool is part of Graphviz (see: + # http://www.graphviz.org/), a graph visualization toolkit from AT&T + # and Lucent Bell Labs. The other options in this section have no + # effect if this option is set to NO. + # Doxygen's default value is: NO. + if(Doxygen_dot_FOUND) + set(DOXYGEN_HAVE_DOT "YES") + else() + set(DOXYGEN_HAVE_DOT "NO") + endif() + endif() + + if(NOT DEFINED DOXYGEN_DOT_MULTI_TARGETS) + # Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate + # multiple output files in one run (i.e. multiple -o and -T options on + # the command line). This makes dot run faster, but since only newer + # versions of dot (>1.8.10) support this, Doxygen disables this feature + # by default. + # This tag requires that the tag HAVE_DOT is set to YES. + set(DOXYGEN_DOT_MULTI_TARGETS YES) + endif() + + if(NOT DEFINED DOXYGEN_GENERATE_LATEX) + # If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX + # output. We only want the HTML output enabled by default, so we turn + # this off if the project hasn't specified it. + set(DOXYGEN_GENERATE_LATEX NO) + endif() + + if(NOT DEFINED DOXYGEN_WARN_FORMAT) + if(CMAKE_VS_MSBUILD_COMMAND OR CMAKE_VS_DEVENV_COMMAND) + # The WARN_FORMAT tag determines the format of the warning messages + # that doxygen can produce. The string should contain the $file, + # $line and $text tags, which will be replaced by the file and line + # number from which the warning originated and the warning text. + # Optionally, the format may contain $version, which will be + # replaced by the version of the file (if it could be obtained via + # FILE_VERSION_FILTER). + # Doxygen's default value is: $file:$line: $text + set(DOXYGEN_WARN_FORMAT "$file($line) : $text ") + endif() + endif() + + if(DEFINED DOXYGEN_WARN_LOGFILE AND NOT IS_ABSOLUTE "${DOXYGEN_WARN_LOGFILE}") + # The WARN_LOGFILE tag can be used to specify a file to which warning and error + # messages should be written. If left blank the output is written to standard + # error (stderr). + get_filename_component(DOXYGEN_WARN_LOGFILE + "${DOXYGEN_WARN_LOGFILE}" + ABSOLUTE + BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}") + endif() + + # Any files from the INPUT that match any of the EXCLUDE_PATTERNS will be + # excluded from the set of input files. We provide some additional patterns + # to prevent commonly unwanted things from CMake builds being pulled in. + # + # Note that the wildcards are matched against the file with absolute path, + # so to exclude all test directories for example use the pattern */test/* + list( + APPEND + DOXYGEN_EXCLUDE_PATTERNS + "*/.git/*" + "*/.svn/*" + "*/.hg/*" + "*/CMakeFiles/*" + "*/_CPack_Packages/*" + "DartConfiguration.tcl" + "CMakeLists.txt" + "CMakeCache.txt" + ) + + # Now bring in Doxgen's defaults for those things the project has not + # already set and we have not provided above + include("${CMAKE_BINARY_DIR}/CMakeDoxygenDefaults.cmake" OPTIONAL) + + # Cleanup built HTMLs on "make clean" + # TODO Any other dirs? + if(DOXYGEN_GENERATE_HTML) + if(IS_ABSOLUTE "${DOXYGEN_HTML_OUTPUT}") + set(_args_clean_html_dir "${DOXYGEN_HTML_OUTPUT}") + else() + set(_args_clean_html_dir + "${DOXYGEN_OUTPUT_DIRECTORY}/${DOXYGEN_HTML_OUTPUT}") + endif() + set_property(DIRECTORY APPEND PROPERTY + ADDITIONAL_MAKE_CLEAN_FILES "${_args_clean_html_dir}") + endif() + + # Build up a list of files we can identify from the inputs so we can list + # them as SOURCES in the custom target (makes them display in IDEs). We + # must do this before we transform the various DOXYGEN_... variables below + # because we need to process DOXYGEN_INPUT as a list first. + unset(_sources) + foreach(_item IN LISTS DOXYGEN_INPUT) + get_filename_component(_abs_item "${_item}" ABSOLUTE + BASE_DIR "${_args_WORKING_DIRECTORY}") + if(EXISTS "${_abs_item}" AND + NOT IS_DIRECTORY "${_abs_item}" AND + NOT IS_SYMLINK "${_abs_item}") + list(APPEND _sources "${_abs_item}") + endif() + endforeach() + if(_sources) + list(INSERT _sources 0 SOURCES) + endif() + + # Transform known list type options into space separated strings. + set(_doxygen_list_options + ABBREVIATE_BRIEF + ALIASES + CITE_BIB_FILES + DIAFILE_DIRS + DOTFILE_DIRS + DOT_FONTPATH + ENABLED_SECTIONS + EXAMPLE_PATH + EXAMPLE_PATTERNS + EXCLUDE + EXCLUDE_PATTERNS + EXCLUDE_SYMBOLS + EXPAND_AS_DEFINED + EXTENSION_MAPPING + EXTRA_PACKAGES + EXTRA_SEARCH_MAPPINGS + FILE_PATTERNS + FILTER_PATTERNS + FILTER_SOURCE_PATTERNS + HTML_EXTRA_FILES + HTML_EXTRA_STYLESHEET + IGNORE_PREFIX + IMAGE_PATH + INCLUDE_FILE_PATTERNS + INCLUDE_PATH + INPUT + LATEX_EXTRA_FILES + LATEX_EXTRA_STYLESHEET + MATHJAX_EXTENSIONS + MSCFILE_DIRS + PLANTUML_INCLUDE_PATH + PREDEFINED + QHP_CUST_FILTER_ATTRS + QHP_SECT_FILTER_ATTRS + STRIP_FROM_INC_PATH + STRIP_FROM_PATH + TAGFILES + TCL_SUBST + ) + foreach(_item IN LISTS _doxygen_list_options) + doxygen_list_to_quoted_strings(DOXYGEN_${_item}) + endforeach() + + # Transform known single value variables which may contain spaces, such as + # paths or description strings. + set(_doxygen_quoted_options + CHM_FILE + DIA_PATH + DOCBOOK_OUTPUT + DOCSET_FEEDNAME + DOCSET_PUBLISHER_NAME + DOT_FONTNAME + DOT_PATH + EXTERNAL_SEARCH_ID + FILE_VERSION_FILTER + GENERATE_TAGFILE + HHC_LOCATION + HTML_FOOTER + HTML_HEADER + HTML_OUTPUT + HTML_STYLESHEET + INPUT_FILTER + LATEX_FOOTER + LATEX_HEADER + LATEX_OUTPUT + LAYOUT_FILE + MAN_OUTPUT + MAN_SUBDIR + MATHJAX_CODEFILE + MSCGEN_PATH + OUTPUT_DIRECTORY + PERL_PATH + PLANTUML_JAR_PATH + PROJECT_BRIEF + PROJECT_LOGO + PROJECT_NAME + QCH_FILE + QHG_LOCATION + QHP_CUST_FILTER_NAME + QHP_VIRTUAL_FOLDER + RTF_EXTENSIONS_FILE + RTF_OUTPUT + RTF_STYLESHEET_FILE + SEARCHDATA_FILE + USE_MDFILE_AS_MAINPAGE + WARN_FORMAT + WARN_LOGFILE + XML_OUTPUT + ) + + # Store the unmodified value of DOXYGEN_OUTPUT_DIRECTORY prior to invoking + # doxygen_quote_value() below. This will mutate the string specifically for + # consumption by Doxygen's config file, which we do not want when we use it + # later in the custom target's commands. + set( _original_doxygen_output_dir ${DOXYGEN_OUTPUT_DIRECTORY} ) + + foreach(_item IN LISTS _doxygen_quoted_options) + doxygen_quote_value(DOXYGEN_${_item}) + endforeach() + + # Prepare doxygen configuration file + set(_doxyfile_template "${CMAKE_BINARY_DIR}/CMakeDoxyfile.in") + set(_target_doxyfile "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.${targetName}") + configure_file("${_doxyfile_template}" "${_target_doxyfile}") + + unset(_all) + if(${_args_ALL}) + set(_all ALL) + endif() + + # Add the target + add_custom_target( ${targetName} ${_all} VERBATIM + COMMAND ${CMAKE_COMMAND} -E make_directory ${_original_doxygen_output_dir} + COMMAND "${DOXYGEN_EXECUTABLE}" "${_target_doxyfile}" + WORKING_DIRECTORY "${_args_WORKING_DIRECTORY}" + DEPENDS "${_target_doxyfile}" + COMMENT "${_args_COMMENT}" + ${_sources} + ) + +endfunction() + +cmake_policy(POP) diff --git a/Kommon/cmake/FindGSL.cmake b/Kommon/cmake/FindGSL.cmake index 8d10b6ce5..db0512166 100644 --- a/Kommon/cmake/FindGSL.cmake +++ b/Kommon/cmake/FindGSL.cmake @@ -1,60 +1,61 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -#.rst: -# FindGSL -# -------- -# -# Find the native GSL includes and libraries. -# -# The GNU Scientific Library (GSL) is a numerical library for C and C++ -# programmers. It is free software under the GNU General Public -# License. -# -# Imported Targets -# ^^^^^^^^^^^^^^^^ -# -# If GSL is found, this module defines the following :prop_tgt:`IMPORTED` -# targets:: -# -# GSL::gsl - The main GSL library. -# GSL::gslcblas - The CBLAS support library used by GSL. -# -# Result Variables -# ^^^^^^^^^^^^^^^^ -# -# This module will set the following variables in your project:: -# -# GSL_FOUND - True if GSL found on the local system -# GSL_INCLUDE_DIRS - Location of GSL header files. -# GSL_LIBRARIES - The GSL libraries. -# GSL_VERSION - The version of the discovered GSL install. -# -# Hints -# ^^^^^ -# -# Set ``GSL_ROOT_DIR`` to a directory that contains a GSL installation. -# -# This script expects to find libraries at ``$GSL_ROOT_DIR/lib`` and the GSL -# headers at ``$GSL_ROOT_DIR/include/gsl``. The library directory may -# optionally provide Release and Debug folders. If available, the libraries -# named ``gsld``, ``gslblasd`` or ``cblasd`` are recognized as debug libraries. -# For Unix-like systems, this script will use ``$GSL_ROOT_DIR/bin/gsl-config`` -# (if found) to aid in the discovery of GSL. -# -# Cache Variables -# ^^^^^^^^^^^^^^^ -# -# This module may set the following variables depending on platform and type -# of GSL installation discovered. These variables may optionally be set to -# help this module find the correct files:: -# -# GSL_CBLAS_LIBRARY - Location of the GSL CBLAS library. -# GSL_CBLAS_LIBRARY_DEBUG - Location of the debug GSL CBLAS library (if any). -# GSL_CONFIG_EXECUTABLE - Location of the ``gsl-config`` script (if any). -# GSL_LIBRARY - Location of the GSL library. -# GSL_LIBRARY_DEBUG - Location of the debug GSL library (if any). -# +#[=======================================================================[.rst: +FindGSL +-------- + +Find the native GSL includes and libraries. + +The GNU Scientific Library (GSL) is a numerical library for C and C++ +programmers. It is free software under the GNU General Public +License. + +Imported Targets +^^^^^^^^^^^^^^^^ + +If GSL is found, this module defines the following :prop_tgt:`IMPORTED` +targets:: + + GSL::gsl - The main GSL library. + GSL::gslcblas - The CBLAS support library used by GSL. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables in your project:: + + GSL_FOUND - True if GSL found on the local system + GSL_INCLUDE_DIRS - Location of GSL header files. + GSL_LIBRARIES - The GSL libraries. + GSL_VERSION - The version of the discovered GSL install. + +Hints +^^^^^ + +Set ``GSL_ROOT_DIR`` to a directory that contains a GSL installation. + +This script expects to find libraries at ``$GSL_ROOT_DIR/lib`` and the GSL +headers at ``$GSL_ROOT_DIR/include/gsl``. The library directory may +optionally provide Release and Debug folders. If available, the libraries +named ``gsld``, ``gslblasd`` or ``cblasd`` are recognized as debug libraries. +For Unix-like systems, this script will use ``$GSL_ROOT_DIR/bin/gsl-config`` +(if found) to aid in the discovery of GSL. + +Cache Variables +^^^^^^^^^^^^^^^ + +This module may set the following variables depending on platform and type +of GSL installation discovered. These variables may optionally be set to +help this module find the correct files:: + + GSL_CBLAS_LIBRARY - Location of the GSL CBLAS library. + GSL_CBLAS_LIBRARY_DEBUG - Location of the debug GSL CBLAS library (if any). + GSL_CONFIG_EXECUTABLE - Location of the ``gsl-config`` script (if any). + GSL_LIBRARY - Location of the GSL library. + GSL_LIBRARY_DEBUG - Location of the debug GSL library (if any). + +#]=======================================================================] include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) diff --git a/Kommon/cmake/FindHDF5.cmake b/Kommon/cmake/FindHDF5.cmake new file mode 100644 index 000000000..70bfc96f1 --- /dev/null +++ b/Kommon/cmake/FindHDF5.cmake @@ -0,0 +1,957 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindHDF5 +-------- + +Find HDF5, a library for reading and writing self describing array data. + + +This module invokes the HDF5 wrapper compiler that should be installed +alongside HDF5. Depending upon the HDF5 Configuration, the wrapper +compiler is called either h5cc or h5pcc. If this succeeds, the module +will then call the compiler with the -show argument to see what flags +are used when compiling an HDF5 client application. + +The module will optionally accept the COMPONENTS argument. If no +COMPONENTS are specified, then the find module will default to finding +only the HDF5 C library. If one or more COMPONENTS are specified, the +module will attempt to find the language bindings for the specified +components. The only valid components are C, CXX, Fortran, HL, and +Fortran_HL. If the COMPONENTS argument is not given, the module will +attempt to find only the C bindings. + +This module will read the variable +HDF5_USE_STATIC_LIBRARIES to determine whether or not to prefer a +static link to a dynamic link for HDF5 and all of it's dependencies. +To use this feature, make sure that the HDF5_USE_STATIC_LIBRARIES +variable is set before the call to find_package. + +To provide the module with a hint about where to find your HDF5 +installation, you can set the environment variable HDF5_ROOT. The +Find module will then look in this path when searching for HDF5 +executables, paths, and libraries. + +Both the serial and parallel HDF5 wrappers are considered and the first +directory to contain either one will be used. In the event that both appear +in the same directory the serial version is preferentially selected. This +behavior can be reversed by setting the variable HDF5_PREFER_PARALLEL to +true. + +In addition to finding the includes and libraries required to compile +an HDF5 client application, this module also makes an effort to find +tools that come with the HDF5 distribution that may be useful for +regression testing. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables in your project: + +``HDF5_FOUND`` + HDF5 was found on the system +``HDF5_VERSION`` + HDF5 library version +``HDF5_INCLUDE_DIRS`` + Location of the HDF5 header files +``HDF5_DEFINITIONS`` + Required compiler definitions for HDF5 +``HDF5_LIBRARIES`` + Required libraries for all requested bindings +``HDF5_HL_LIBRARIES`` + Required libraries for the HDF5 high level API for all bindings, + if the ``HL`` component is enabled + +Available components are: ``C`` ``CXX`` ``Fortran`` and ``HL``. +For each enabled language binding, a corresponding ``HDF5_${LANG}_LIBRARIES`` +variable, and potentially ``HDF5_${LANG}_DEFINITIONS``, will be defined. +If the ``HL`` component is enabled, then an ``HDF5_${LANG}_HL_LIBRARIES`` will +also be defined. With all components enabled, the following variables will be defined: + +``HDF5_C_DEFINITIONS`` + Required compiler definitions for HDF5 C bindings +``HDF5_CXX_DEFINITIONS`` + Required compiler definitions for HDF5 C++ bindings +``HDF5_Fortran_DEFINITIONS`` + Required compiler definitions for HDF5 Fortran bindings +``HDF5_C_INCLUDE_DIRS`` + Required include directories for HDF5 C bindings +``HDF5_CXX_INCLUDE_DIRS`` + Required include directories for HDF5 C++ bindings +``HDF5_Fortran_INCLUDE_DIRS`` + Required include directories for HDF5 Fortran bindings +``HDF5_C_LIBRARIES`` + Required libraries for the HDF5 C bindings +``HDF5_CXX_LIBRARIES`` + Required libraries for the HDF5 C++ bindings +``HDF5_Fortran_LIBRARIES`` + Required libraries for the HDF5 Fortran bindings +``HDF5_C_HL_LIBRARIES`` + Required libraries for the high level C bindings +``HDF5_CXX_HL_LIBRARIES`` + Required libraries for the high level C++ bindings +``HDF5_Fortran_HL_LIBRARIES`` + Required libraries for the high level Fortran bindings. + +``HDF5_IS_PARALLEL`` + HDF5 library has parallel IO support +``HDF5_C_COMPILER_EXECUTABLE`` + path to the HDF5 C wrapper compiler +``HDF5_CXX_COMPILER_EXECUTABLE`` + path to the HDF5 C++ wrapper compiler +``HDF5_Fortran_COMPILER_EXECUTABLE`` + path to the HDF5 Fortran wrapper compiler +``HDF5_C_COMPILER_EXECUTABLE_NO_INTERROGATE`` + path to the primary C compiler which is also the HDF5 wrapper +``HDF5_CXX_COMPILER_EXECUTABLE_NO_INTERROGATE`` + path to the primary C++ compiler which is also the HDF5 wrapper +``HDF5_Fortran_COMPILER_EXECUTABLE_NO_INTERROGATE`` + path to the primary Fortran compiler which is also the HDF5 wrapper +``HDF5_DIFF_EXECUTABLE`` + path to the HDF5 dataset comparison tool + +Hints +^^^^^ + +The following variable can be set to guide the search for HDF5 libraries and includes: + +``HDF5_ROOT`` + Specify the path to the HDF5 installation to use. + +``HDF5_FIND_DEBUG`` + Set ``true`` to get extra debugging output. + +``HDF5_NO_FIND_PACKAGE_CONFIG_FILE`` + Set ``true`` to skip trying to find ``hdf5-config.cmake``. +#]=======================================================================] + +# This module is maintained by Will Dicharry . + +include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) + +# List of the valid HDF5 components +set(HDF5_VALID_LANGUAGE_BINDINGS C CXX Fortran) + +# Validate the list of find components. +if(NOT HDF5_FIND_COMPONENTS) + set(HDF5_LANGUAGE_BINDINGS "C") +else() + set(HDF5_LANGUAGE_BINDINGS) + # add the extra specified components, ensuring that they are valid. + set(FIND_HL OFF) + foreach(component IN LISTS HDF5_FIND_COMPONENTS) + list(FIND HDF5_VALID_LANGUAGE_BINDINGS ${component} component_location) + if(NOT component_location EQUAL -1) + list(APPEND HDF5_LANGUAGE_BINDINGS ${component}) + elseif(component STREQUAL "HL") + set(FIND_HL ON) + elseif(component STREQUAL "Fortran_HL") # only for compatibility + list(APPEND HDF5_LANGUAGE_BINDINGS Fortran) + set(FIND_HL ON) + set(HDF5_FIND_REQUIRED_Fortran_HL False) + set(HDF5_FIND_REQUIRED_Fortran True) + set(HDF5_FIND_REQUIRED_HL True) + else() + message(FATAL_ERROR "${component} is not a valid HDF5 component.") + endif() + endforeach() + if(NOT HDF5_LANGUAGE_BINDINGS) + get_property(__langs GLOBAL PROPERTY ENABLED_LANGUAGES) + foreach(__lang IN LISTS __langs) + if(__lang MATCHES "^(C|CXX|Fortran)$") + list(APPEND HDF5_LANGUAGE_BINDINGS ${__lang}) + endif() + endforeach() + endif() + list(REMOVE_ITEM HDF5_FIND_COMPONENTS Fortran_HL) # replaced by Fortran and HL + list(REMOVE_DUPLICATES HDF5_LANGUAGE_BINDINGS) +endif() + +# Determine whether to search for serial or parallel executable first +if(HDF5_PREFER_PARALLEL) + set(HDF5_C_COMPILER_NAMES h5pcc h5cc) + set(HDF5_CXX_COMPILER_NAMES h5pc++ h5c++) + set(HDF5_Fortran_COMPILER_NAMES h5pfc h5fc) +else() + set(HDF5_C_COMPILER_NAMES h5cc h5pcc) + set(HDF5_CXX_COMPILER_NAMES h5c++ h5pc++) + set(HDF5_Fortran_COMPILER_NAMES h5fc h5pfc) +endif() + +# We may have picked up some duplicates in various lists during the above +# process for the language bindings (both the C and C++ bindings depend on +# libz for example). Remove the duplicates. It appears that the default +# CMake behavior is to remove duplicates from the end of a list. However, +# for link lines, this is incorrect since unresolved symbols are searched +# for down the link line. Therefore, we reverse the list, remove the +# duplicates, and then reverse it again to get the duplicates removed from +# the beginning. +macro(_HDF5_remove_duplicates_from_beginning _list_name) + if(${_list_name}) + list(REVERSE ${_list_name}) + list(REMOVE_DUPLICATES ${_list_name}) + list(REVERSE ${_list_name}) + endif() +endmacro() + + +# Test first if the current compilers automatically wrap HDF5 + +function(_HDF5_test_regular_compiler_C success version is_parallel) + set(scratch_directory + ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5) + if(NOT ${success} OR + NOT EXISTS ${scratch_directory}/compiler_has_h5_c) + set(test_file ${scratch_directory}/cmake_hdf5_test.c) + file(WRITE ${test_file} + "#include \n" + "#include \n" + "const char* info_ver = \"INFO\" \":\" H5_VERSION;\n" + "#ifdef H5_HAVE_PARALLEL\n" + "const char* info_parallel = \"INFO\" \":\" \"PARALLEL\";\n" + "#endif\n" + "int main(int argc, char **argv) {\n" + " int require = 0;\n" + " require += info_ver[argc];\n" + "#ifdef H5_HAVE_PARALLEL\n" + " require += info_parallel[argc];\n" + "#endif\n" + " hid_t fid;\n" + " fid = H5Fcreate(\"foo.h5\",H5F_ACC_TRUNC,H5P_DEFAULT,H5P_DEFAULT);\n" + " return 0;\n" + "}") + try_compile(${success} ${scratch_directory} ${test_file} + COPY_FILE ${scratch_directory}/compiler_has_h5_c + ) + endif() + if(${success}) + file(STRINGS ${scratch_directory}/compiler_has_h5_c INFO_STRINGS + REGEX "^INFO:" + ) + string(REGEX MATCH "^INFO:([0-9]+\\.[0-9]+\\.[0-9]+)(-patch([0-9]+))?" + INFO_VER "${INFO_STRINGS}" + ) + set(${version} ${CMAKE_MATCH_1}) + if(CMAKE_MATCH_3) + set(${version} ${HDF5_C_VERSION}.${CMAKE_MATCH_3}) + endif() + set(${version} ${${version}} PARENT_SCOPE) + + if(INFO_STRINGS MATCHES "INFO:PARALLEL") + set(${is_parallel} TRUE PARENT_SCOPE) + else() + set(${is_parallel} FALSE PARENT_SCOPE) + endif() + endif() +endfunction() + +function(_HDF5_test_regular_compiler_CXX success version is_parallel) + set(scratch_directory ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5) + if(NOT ${success} OR + NOT EXISTS ${scratch_directory}/compiler_has_h5_cxx) + set(test_file ${scratch_directory}/cmake_hdf5_test.cxx) + file(WRITE ${test_file} + "#include \n" + "#ifndef H5_NO_NAMESPACE\n" + "using namespace H5;\n" + "#endif\n" + "const char* info_ver = \"INFO\" \":\" H5_VERSION;\n" + "#ifdef H5_HAVE_PARALLEL\n" + "const char* info_parallel = \"INFO\" \":\" \"PARALLEL\";\n" + "#endif\n" + "int main(int argc, char **argv) {\n" + " int require = 0;\n" + " require += info_ver[argc];\n" + "#ifdef H5_HAVE_PARALLEL\n" + " require += info_parallel[argc];\n" + "#endif\n" + " H5File file(\"foo.h5\", H5F_ACC_TRUNC);\n" + " return 0;\n" + "}") + try_compile(${success} ${scratch_directory} ${test_file} + COPY_FILE ${scratch_directory}/compiler_has_h5_cxx + ) + endif() + if(${success}) + file(STRINGS ${scratch_directory}/compiler_has_h5_cxx INFO_STRINGS + REGEX "^INFO:" + ) + string(REGEX MATCH "^INFO:([0-9]+\\.[0-9]+\\.[0-9]+)(-patch([0-9]+))?" + INFO_VER "${INFO_STRINGS}" + ) + set(${version} ${CMAKE_MATCH_1}) + if(CMAKE_MATCH_3) + set(${version} ${HDF5_CXX_VERSION}.${CMAKE_MATCH_3}) + endif() + set(${version} ${${version}} PARENT_SCOPE) + + if(INFO_STRINGS MATCHES "INFO:PARALLEL") + set(${is_parallel} TRUE PARENT_SCOPE) + else() + set(${is_parallel} FALSE PARENT_SCOPE) + endif() + endif() +endfunction() + +function(_HDF5_test_regular_compiler_Fortran success is_parallel) + if(NOT ${success}) + set(scratch_directory + ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5) + set(test_file ${scratch_directory}/cmake_hdf5_test.f90) + file(WRITE ${test_file} + "program hdf5_hello\n" + " use hdf5\n" + " use h5lt\n" + " use h5ds\n" + " integer error\n" + " call h5open_f(error)\n" + " call h5close_f(error)\n" + "end\n") + try_compile(${success} ${scratch_directory} ${test_file}) + if(${success}) + execute_process(COMMAND ${CMAKE_Fortran_COMPILER} -showconfig + OUTPUT_VARIABLE config_output + ERROR_VARIABLE config_error + RESULT_VARIABLE config_result + ) + if(config_output MATCHES "Parallel HDF5: yes") + set(${is_parallel} TRUE PARENT_SCOPE) + else() + set(${is_parallel} FALSE PARENT_SCOPE) + endif() + endif() + endif() +endfunction() + +# Invoke the HDF5 wrapper compiler. The compiler return value is stored to the +# return_value argument, the text output is stored to the output variable. +macro( _HDF5_invoke_compiler language output return_value version is_parallel) + set(${version}) + if(HDF5_USE_STATIC_LIBRARIES) + set(lib_type_args -noshlib) + else() + set(lib_type_args -shlib) + endif() + set(scratch_dir ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5) + if("${language}" STREQUAL "C") + set(test_file ${scratch_dir}/cmake_hdf5_test.c) + elseif("${language}" STREQUAL "CXX") + set(test_file ${scratch_dir}/cmake_hdf5_test.cxx) + elseif("${language}" STREQUAL "Fortran") + set(test_file ${scratch_dir}/cmake_hdf5_test.f90) + endif() + execute_process( + COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -show ${lib_type_args} ${test_file} + OUTPUT_VARIABLE ${output} + ERROR_VARIABLE ${output} + RESULT_VARIABLE ${return_value} + ) + if(NOT ${${return_value}} EQUAL 0) + message(STATUS + "Unable to determine HDF5 ${language} flags from HDF5 wrapper.") + endif() + execute_process( + COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -showconfig + OUTPUT_VARIABLE config_output + ERROR_VARIABLE config_output + RESULT_VARIABLE config_return + ) + if(NOT ${return_value} EQUAL 0) + message( STATUS + "Unable to determine HDF5 ${language} version from HDF5 wrapper.") + endif() + string(REGEX MATCH "HDF5 Version: ([a-zA-Z0-9\\.\\-]*)" version_match "${config_output}") + if(version_match) + string(REPLACE "HDF5 Version: " "" ${version} "${version_match}") + string(REPLACE "-patch" "." ${version} "${${version}}") + endif() + if(config_output MATCHES "Parallel HDF5: yes") + set(${is_parallel} TRUE) + else() + set(${is_parallel} FALSE) + endif() +endmacro() + +# Parse a compile line for definitions, includes, library paths, and libraries. +macro( _HDF5_parse_compile_line + compile_line_var + include_paths + definitions + library_paths + libraries + libraries_hl) + + separate_arguments(_HDF5_COMPILE_ARGS NATIVE_COMMAND "${${compile_line_var}}") + + foreach(arg IN LISTS _HDF5_COMPILE_ARGS) + if("${arg}" MATCHES "^-I(.*)$") + # include directory + list(APPEND ${include_paths} "${CMAKE_MATCH_1}") + elseif("${arg}" MATCHES "^-D(.*)$") + # compile definition + list(APPEND ${definitions} "-D${CMAKE_MATCH_1}") + elseif("${arg}" MATCHES "^-L(.*)$") + # library search path + list(APPEND ${library_paths} "${CMAKE_MATCH_1}") + elseif("${arg}" MATCHES "^-l(hdf5.*hl.*)$") + # library name (hl) + list(APPEND ${libraries_hl} "${CMAKE_MATCH_1}") + elseif("${arg}" MATCHES "^-l(.*)$") + # library name + list(APPEND ${libraries} "${CMAKE_MATCH_1}") + elseif("${arg}" MATCHES "^(.:)?[/\\].*\\.(a|so|dylib|sl|lib)$") + # library file + if(NOT EXISTS "${arg}") + continue() + endif() + get_filename_component(_HDF5_LPATH "${arg}" DIRECTORY) + get_filename_component(_HDF5_LNAME "${arg}" NAME_WE) + string(REGEX REPLACE "^lib" "" _HDF5_LNAME "${_HDF5_LNAME}") + list(APPEND ${library_paths} "${_HDF5_LPATH}") + if(_HDF5_LNAME MATCHES "hdf5.*hl") + list(APPEND ${libraries_hl} "${_HDF5_LNAME}") + else() + list(APPEND ${libraries} "${_HDF5_LNAME}") + endif() + endif() + endforeach() +endmacro() + +# Select a preferred imported configuration from a target +function(_HDF5_select_imported_config target imported_conf) + # We will first assign the value to a local variable _imported_conf, then assign + # it to the function argument at the end. + get_target_property(_imported_conf ${target} MAP_IMPORTED_CONFIG_${CMAKE_BUILD_TYPE}) + if (NOT _imported_conf) + # Get available imported configurations by examining target properties + get_target_property(_imported_conf ${target} IMPORTED_CONFIGURATIONS) + if(HDF5_FIND_DEBUG) + message(STATUS "Found imported configurations: ${_imported_conf}") + endif() + # Find the imported configuration that we prefer. + # We do this by making list of configurations in order of preference, + # starting with ${CMAKE_BUILD_TYPE} and ending with the first imported_conf + set(_preferred_confs ${CMAKE_BUILD_TYPE}) + list(GET _imported_conf 0 _fallback_conf) + list(APPEND _preferred_confs RELWITHDEBINFO RELEASE DEBUG ${_fallback_conf}) + if(HDF5_FIND_DEBUG) + message(STATUS "Start search through imported configurations in the following order: ${_preferred_confs}") + endif() + # Now find the first of these that is present in imported_conf + cmake_policy(PUSH) + cmake_policy(SET CMP0057 NEW) # support IN_LISTS + foreach (_conf IN LISTS _preferred_confs) + if (${_conf} IN_LIST _imported_conf) + set(_imported_conf ${_conf}) + break() + endif() + endforeach() + cmake_policy(POP) + endif() + if(HDF5_FIND_DEBUG) + message(STATUS "Selected imported configuration: ${_imported_conf}") + endif() + # assign value to function argument + set(${imported_conf} ${_imported_conf} PARENT_SCOPE) +endfunction() + + +if(NOT HDF5_ROOT) + set(HDF5_ROOT $ENV{HDF5_ROOT}) +endif() +if(HDF5_ROOT) + set(_HDF5_SEARCH_OPTS NO_DEFAULT_PATH) +else() + set(_HDF5_SEARCH_OPTS) +endif() + +# Try to find HDF5 using an installed hdf5-config.cmake +if(NOT HDF5_FOUND AND NOT HDF5_NO_FIND_PACKAGE_CONFIG_FILE) + find_package(HDF5 QUIET NO_MODULE + HINTS ${HDF5_ROOT} + ${_HDF5_SEARCH_OPTS} + ) + if( HDF5_FOUND) + if(HDF5_FIND_DEBUG) + message(STATUS "Found HDF5 at ${HDF5_DIR} via NO_MODULE. Now trying to extract locations etc.") + endif() + set(HDF5_IS_PARALLEL ${HDF5_ENABLE_PARALLEL}) + set(HDF5_INCLUDE_DIRS ${HDF5_INCLUDE_DIR}) + set(HDF5_LIBRARIES) + if (NOT TARGET hdf5 AND NOT TARGET hdf5-static AND NOT TARGET hdf5-shared) + # Some HDF5 versions (e.g. 1.8.18) used hdf5::hdf5 etc + set(_target_prefix "hdf5::") + endif() + set(HDF5_C_TARGET ${_target_prefix}hdf5) + set(HDF5_C_HL_TARGET ${_target_prefix}hdf5_hl) + set(HDF5_CXX_TARGET ${_target_prefix}hdf5_cpp) + set(HDF5_CXX_HL_TARGET ${_target_prefix}hdf5_hl_cpp) + set(HDF5_Fortran_TARGET ${_target_prefix}hdf5_fortran) + set(HDF5_Fortran_HL_TARGET ${_target_prefix}hdf5_hl_fortran) + set(HDF5_DEFINITIONS "") + if(HDF5_USE_STATIC_LIBRARIES) + set(_suffix "-static") + else() + set(_suffix "-shared") + endif() + foreach(_lang ${HDF5_LANGUAGE_BINDINGS}) + + #Older versions of hdf5 don't have a static/shared suffix so + #if we detect that occurrence clear the suffix + if(_suffix AND NOT TARGET ${HDF5_${_lang}_TARGET}${_suffix}) + if(NOT TARGET ${HDF5_${_lang}_TARGET}) + #can't find this component with or without the suffix + #so bail out, and let the following locate HDF5 + set(HDF5_FOUND FALSE) + break() + endif() + set(_suffix "") + endif() + + if(HDF5_FIND_DEBUG) + message(STATUS "Trying to get properties of target ${HDF5_${_lang}_TARGET}${_suffix}") + endif() + # Find library for this target. Complicated as on Windows with a DLL, we need to search for the import-lib. + _HDF5_select_imported_config(${HDF5_${_lang}_TARGET}${_suffix} _hdf5_imported_conf) + get_target_property(_hdf5_lang_location ${HDF5_${_lang}_TARGET}${_suffix} IMPORTED_IMPLIB_${_hdf5_imported_conf} ) + if (NOT _hdf5_lang_location) + # no import lib, just try LOCATION + get_target_property(_hdf5_lang_location ${HDF5_${_lang}_TARGET}${_suffix} LOCATION_${_hdf5_imported_conf}) + if (NOT _hdf5_lang_location) + get_target_property(_hdf5_lang_location ${HDF5_${_lang}_TARGET}${_suffix} LOCATION) + endif() + endif() + if( _hdf5_lang_location ) + set(HDF5_${_lang}_LIBRARY ${_hdf5_lang_location}) + list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix}) + set(HDF5_${_lang}_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix}) + set(HDF5_${_lang}_FOUND True) + endif() + if(FIND_HL) + get_target_property(__lang_hl_location ${HDF5_${_lang}_HL_TARGET}${_suffix} IMPORTED_IMPLIB_${_hdf5_imported_conf} ) + if (NOT _hdf5_lang_hl_location) + get_target_property(_hdf5_lang_hl_location ${HDF5_${_lang}_HL_TARGET}${_suffix} LOCATION_${_hdf5_imported_conf}) + if (NOT _hdf5_hl_lang_location) + get_target_property(_hdf5_hl_lang_location ${HDF5_${_lang}_HL_TARGET}${_suffix} LOCATION) + endif() + endif() + if( _hdf5_lang_hl_location ) + set(HDF5_${_lang}_HL_LIBRARY ${_hdf5_lang_hl_location}) + list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_TARGET}${_suffix}) + set(HDF5_${_lang}_HL_LIBRARIES ${HDF5_${_lang}_HL_TARGET}${_suffix}) + set(HDF5_HL_FOUND True) + endif() + unset(_hdf5_lang_hl_location) + endif() + unset(_hdf5_imported_conf) + unset(_hdf5_lang_location) + endforeach() + endif() +endif() + +if(NOT HDF5_FOUND) + set(_HDF5_NEED_TO_SEARCH False) + set(HDF5_COMPILER_NO_INTERROGATE True) + # Only search for languages we've enabled + foreach(__lang IN LISTS HDF5_LANGUAGE_BINDINGS) + # First check to see if our regular compiler is one of wrappers + if(__lang STREQUAL "C") + _HDF5_test_regular_compiler_C( + HDF5_${__lang}_COMPILER_NO_INTERROGATE + HDF5_${__lang}_VERSION + HDF5_${__lang}_IS_PARALLEL) + elseif(__lang STREQUAL "CXX") + _HDF5_test_regular_compiler_CXX( + HDF5_${__lang}_COMPILER_NO_INTERROGATE + HDF5_${__lang}_VERSION + HDF5_${__lang}_IS_PARALLEL) + elseif(__lang STREQUAL "Fortran") + _HDF5_test_regular_compiler_Fortran( + HDF5_${__lang}_COMPILER_NO_INTERROGATE + HDF5_${__lang}_IS_PARALLEL) + else() + continue() + endif() + if(HDF5_${__lang}_COMPILER_NO_INTERROGATE) + message(STATUS "HDF5: Using hdf5 compiler wrapper for all ${__lang} compiling") + set(HDF5_${__lang}_FOUND True) + set(HDF5_${__lang}_COMPILER_EXECUTABLE_NO_INTERROGATE + "${CMAKE_${__lang}_COMPILER}" + CACHE FILEPATH "HDF5 ${__lang} compiler wrapper") + set(HDF5_${__lang}_DEFINITIONS) + set(HDF5_${__lang}_INCLUDE_DIRS) + set(HDF5_${__lang}_LIBRARIES) + set(HDF5_${__lang}_HL_LIBRARIES) + + mark_as_advanced(HDF5_${__lang}_COMPILER_EXECUTABLE_NO_INTERROGATE) + + set(HDF5_${__lang}_FOUND True) + set(HDF5_HL_FOUND True) + else() + set(HDF5_COMPILER_NO_INTERROGATE False) + # If this language isn't using the wrapper, then try to seed the + # search options with the wrapper + find_program(HDF5_${__lang}_COMPILER_EXECUTABLE + NAMES ${HDF5_${__lang}_COMPILER_NAMES} NAMES_PER_DIR + HINTS ${HDF5_ROOT} + PATH_SUFFIXES bin Bin + DOC "HDF5 ${__lang} Wrapper compiler. Used only to detect HDF5 compile flags." + ${_HDF5_SEARCH_OPTS} + ) + mark_as_advanced( HDF5_${__lang}_COMPILER_EXECUTABLE ) + unset(HDF5_${__lang}_COMPILER_NAMES) + + if(HDF5_${__lang}_COMPILER_EXECUTABLE) + _HDF5_invoke_compiler(${__lang} HDF5_${__lang}_COMPILE_LINE + HDF5_${__lang}_RETURN_VALUE HDF5_${__lang}_VERSION HDF5_${__lang}_IS_PARALLEL) + if(HDF5_${__lang}_RETURN_VALUE EQUAL 0) + message(STATUS "HDF5: Using hdf5 compiler wrapper to determine ${__lang} configuration") + _HDF5_parse_compile_line( HDF5_${__lang}_COMPILE_LINE + HDF5_${__lang}_INCLUDE_DIRS + HDF5_${__lang}_DEFINITIONS + HDF5_${__lang}_LIBRARY_DIRS + HDF5_${__lang}_LIBRARY_NAMES + HDF5_${__lang}_HL_LIBRARY_NAMES + ) + set(HDF5_${__lang}_LIBRARIES) + + foreach(L IN LISTS HDF5_${__lang}_LIBRARY_NAMES) + set(_HDF5_SEARCH_NAMES_LOCAL) + if("x${L}" MATCHES "hdf5") + # hdf5 library + set(_HDF5_SEARCH_OPTS_LOCAL ${_HDF5_SEARCH_OPTS}) + if(HDF5_USE_STATIC_LIBRARIES) + if(WIN32) + set(_HDF5_SEARCH_NAMES_LOCAL lib${L}) + else() + set(_HDF5_SEARCH_NAMES_LOCAL lib${L}.a) + endif() + endif() + else() + # external library + set(_HDF5_SEARCH_OPTS_LOCAL) + endif() + find_library(HDF5_${__lang}_LIBRARY_${L} + NAMES ${_HDF5_SEARCH_NAMES_LOCAL} ${L} NAMES_PER_DIR + HINTS ${HDF5_${__lang}_LIBRARY_DIRS} + ${HDF5_ROOT} + ${_HDF5_SEARCH_OPTS_LOCAL} + ) + unset(_HDF5_SEARCH_OPTS_LOCAL) + unset(_HDF5_SEARCH_NAMES_LOCAL) + if(HDF5_${__lang}_LIBRARY_${L}) + list(APPEND HDF5_${__lang}_LIBRARIES ${HDF5_${__lang}_LIBRARY_${L}}) + else() + list(APPEND HDF5_${__lang}_LIBRARIES ${L}) + endif() + endforeach() + if(FIND_HL) + set(HDF5_${__lang}_HL_LIBRARIES) + foreach(L IN LISTS HDF5_${__lang}_HL_LIBRARY_NAMES) + set(_HDF5_SEARCH_NAMES_LOCAL) + if("x${L}" MATCHES "hdf5") + # hdf5 library + set(_HDF5_SEARCH_OPTS_LOCAL ${_HDF5_SEARCH_OPTS}) + if(HDF5_USE_STATIC_LIBRARIES) + if(WIN32) + set(_HDF5_SEARCH_NAMES_LOCAL lib${L}) + else() + set(_HDF5_SEARCH_NAMES_LOCAL lib${L}.a) + endif() + endif() + else() + # external library + set(_HDF5_SEARCH_OPTS_LOCAL) + endif() + find_library(HDF5_${__lang}_LIBRARY_${L} + NAMES ${_HDF5_SEARCH_NAMES_LOCAL} ${L} NAMES_PER_DIR + HINTS ${HDF5_${__lang}_LIBRARY_DIRS} + ${HDF5_ROOT} + ${_HDF5_SEARCH_OPTS_LOCAL} + ) + unset(_HDF5_SEARCH_OPTS_LOCAL) + unset(_HDF5_SEARCH_NAMES_LOCAL) + if(HDF5_${__lang}_LIBRARY_${L}) + list(APPEND HDF5_${__lang}_HL_LIBRARIES ${HDF5_${__lang}_LIBRARY_${L}}) + else() + list(APPEND HDF5_${__lang}_HL_LIBRARIES ${L}) + endif() + endforeach() + set(HDF5_HL_FOUND True) + endif() + + set(HDF5_${__lang}_FOUND True) + _HDF5_remove_duplicates_from_beginning(HDF5_${__lang}_DEFINITIONS) + _HDF5_remove_duplicates_from_beginning(HDF5_${__lang}_INCLUDE_DIRS) + _HDF5_remove_duplicates_from_beginning(HDF5_${__lang}_LIBRARIES) + _HDF5_remove_duplicates_from_beginning(HDF5_${__lang}_HL_LIBRARIES) + else() + set(_HDF5_NEED_TO_SEARCH True) + endif() + else() + set(_HDF5_NEED_TO_SEARCH True) + endif() + endif() + if(HDF5_${__lang}_VERSION) + if(NOT HDF5_VERSION) + set(HDF5_VERSION ${HDF5_${__lang}_VERSION}) + elseif(NOT HDF5_VERSION VERSION_EQUAL HDF5_${__lang}_VERSION) + message(WARNING "HDF5 Version found for language ${__lang}, ${HDF5_${__lang}_VERSION} is different than previously found version ${HDF5_VERSION}") + endif() + endif() + if(DEFINED HDF5_${__lang}_IS_PARALLEL) + if(NOT DEFINED HDF5_IS_PARALLEL) + set(HDF5_IS_PARALLEL ${HDF5_${__lang}_IS_PARALLEL}) + elseif(NOT HDF5_IS_PARALLEL AND HDF5_${__lang}_IS_PARALLEL) + message(WARNING "HDF5 found for language ${__lang} is parallel but previously found language is not parallel.") + elseif(HDF5_IS_PARALLEL AND NOT HDF5_${__lang}_IS_PARALLEL) + message(WARNING "HDF5 found for language ${__lang} is not parallel but previously found language is parallel.") + endif() + endif() + endforeach() +else() + set(_HDF5_NEED_TO_SEARCH True) +endif() + +if(NOT HDF5_FOUND AND HDF5_COMPILER_NO_INTERROGATE) + # No arguments necessary, all languages can use the compiler wrappers + set(HDF5_FOUND True) + set(HDF5_METHOD "Included by compiler wrappers") + set(HDF5_REQUIRED_VARS HDF5_METHOD) +elseif(NOT HDF5_FOUND AND NOT _HDF5_NEED_TO_SEARCH) + # Compiler wrappers aren't being used by the build but were found and used + # to determine necessary include and library flags + set(HDF5_INCLUDE_DIRS) + set(HDF5_LIBRARIES) + set(HDF5_HL_LIBRARIES) + foreach(__lang IN LISTS HDF5_LANGUAGE_BINDINGS) + if(HDF5_${__lang}_FOUND) + if(NOT HDF5_${__lang}_COMPILER_NO_INTERROGATE) + list(APPEND HDF5_DEFINITIONS ${HDF5_${__lang}_DEFINITIONS}) + list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${__lang}_INCLUDE_DIRS}) + list(APPEND HDF5_LIBRARIES ${HDF5_${__lang}_LIBRARIES}) + if(FIND_HL) + list(APPEND HDF5_HL_LIBRARIES ${HDF5_${__lang}_HL_LIBRARIES}) + endif() + endif() + endif() + endforeach() + _HDF5_remove_duplicates_from_beginning(HDF5_DEFINITIONS) + _HDF5_remove_duplicates_from_beginning(HDF5_INCLUDE_DIRS) + _HDF5_remove_duplicates_from_beginning(HDF5_LIBRARIES) + _HDF5_remove_duplicates_from_beginning(HDF5_HL_LIBRARIES) + set(HDF5_FOUND True) + set(HDF5_REQUIRED_VARS HDF5_LIBRARIES) + if(FIND_HL) + list(APPEND HDF5_REQUIRED_VARS HDF5_HL_LIBRARIES) + endif() +endif() + +find_program( HDF5_DIFF_EXECUTABLE + NAMES h5diff + HINTS ${HDF5_ROOT} + PATH_SUFFIXES bin Bin + ${_HDF5_SEARCH_OPTS} + DOC "HDF5 file differencing tool." ) +mark_as_advanced( HDF5_DIFF_EXECUTABLE ) + +if( NOT HDF5_FOUND ) + # seed the initial lists of libraries to find with items we know we need + set(HDF5_C_LIBRARY_NAMES hdf5) + set(HDF5_C_HL_LIBRARY_NAMES hdf5_hl) + + set(HDF5_CXX_LIBRARY_NAMES hdf5_cpp ${HDF5_C_LIBRARY_NAMES}) + set(HDF5_CXX_HL_LIBRARY_NAMES hdf5_hl_cpp ${HDF5_C_HL_LIBRARY_NAMES} ${HDF5_CXX_LIBRARY_NAMES}) + + set(HDF5_Fortran_LIBRARY_NAMES hdf5_fortran ${HDF5_C_LIBRARY_NAMES}) + set(HDF5_Fortran_HL_LIBRARY_NAMES hdf5hl_fortran ${HDF5_C_HL_LIBRARY_NAMES} ${HDF5_Fortran_LIBRARY_NAMES}) + + foreach(__lang IN LISTS HDF5_LANGUAGE_BINDINGS) + # find the HDF5 include directories + if("${__lang}" STREQUAL "Fortran") + set(HDF5_INCLUDE_FILENAME hdf5.mod) + elseif("${__lang}" STREQUAL "CXX") + set(HDF5_INCLUDE_FILENAME H5Cpp.h) + else() + set(HDF5_INCLUDE_FILENAME hdf5.h) + endif() + + find_path(HDF5_${__lang}_INCLUDE_DIR ${HDF5_INCLUDE_FILENAME} + HINTS ${HDF5_ROOT} + PATHS $ENV{HOME}/.local/include + PATH_SUFFIXES include Include + ${_HDF5_SEARCH_OPTS} + ) + mark_as_advanced(HDF5_${__lang}_INCLUDE_DIR) + # set the _DIRS variable as this is what the user will normally use + set(HDF5_${__lang}_INCLUDE_DIRS ${HDF5_${__lang}_INCLUDE_DIR}) + list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${__lang}_INCLUDE_DIR}) + + # find the HDF5 libraries + foreach(LIB IN LISTS HDF5_${__lang}_LIBRARY_NAMES) + if(HDF5_USE_STATIC_LIBRARIES) + # According to bug 1643 on the CMake bug tracker, this is the + # preferred method for searching for a static library. + # See https://gitlab.kitware.com/cmake/cmake/issues/1643. We search + # first for the full static library name, but fall back to a + # generic search on the name if the static search fails. + set( THIS_LIBRARY_SEARCH_DEBUG + lib${LIB}d.a lib${LIB}_debug.a lib${LIB}d lib${LIB}_D lib${LIB}_debug + lib${LIB}d-static.a lib${LIB}_debug-static.a ${LIB}d-static ${LIB}_D-static ${LIB}_debug-static ) + set( THIS_LIBRARY_SEARCH_RELEASE lib${LIB}.a lib${LIB} lib${LIB}-static.a ${LIB}-static) + else() + set( THIS_LIBRARY_SEARCH_DEBUG ${LIB}d ${LIB}_D ${LIB}_debug ${LIB}d-shared ${LIB}_D-shared ${LIB}_debug-shared) + set( THIS_LIBRARY_SEARCH_RELEASE ${LIB} ${LIB}-shared) + if(WIN32) + list(APPEND HDF5_DEFINITIONS "-DH5_BUILT_AS_DYNAMIC_LIB") + endif() + endif() + find_library(HDF5_${LIB}_LIBRARY_DEBUG + NAMES ${THIS_LIBRARY_SEARCH_DEBUG} + HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib + ${_HDF5_SEARCH_OPTS} + ) + find_library( HDF5_${LIB}_LIBRARY_RELEASE + NAMES ${THIS_LIBRARY_SEARCH_RELEASE} + HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib + ${_HDF5_SEARCH_OPTS} + ) + select_library_configurations( HDF5_${LIB} ) + list(APPEND HDF5_${__lang}_LIBRARIES ${HDF5_${LIB}_LIBRARY}) + endforeach() + if(HDF5_${__lang}_LIBRARIES) + set(HDF5_${__lang}_FOUND True) + endif() + + # Append the libraries for this language binding to the list of all + # required libraries. + list(APPEND HDF5_LIBRARIES ${HDF5_${__lang}_LIBRARIES}) + + if(FIND_HL) + foreach(LIB IN LISTS HDF5_${__lang}_HL_LIBRARY_NAMES) + if(HDF5_USE_STATIC_LIBRARIES) + # According to bug 1643 on the CMake bug tracker, this is the + # preferred method for searching for a static library. + # See https://gitlab.kitware.com/cmake/cmake/issues/1643. We search + # first for the full static library name, but fall back to a + # generic search on the name if the static search fails. + set( THIS_LIBRARY_SEARCH_DEBUG + lib${LIB}d.a lib${LIB}_debug.a lib${LIB}d lib${LIB}_D lib${LIB}_debug + lib${LIB}d-static.a lib${LIB}_debug-static.a lib${LIB}d-static lib${LIB}_D-static lib${LIB}_debug-static ) + set( THIS_LIBRARY_SEARCH_RELEASE lib${LIB}.a lib${LIB} lib${LIB}-static.a lib${LIB}-static) + else() + set( THIS_LIBRARY_SEARCH_DEBUG ${LIB}d ${LIB}_D ${LIB}_debug ${LIB}d-shared ${LIB}_D-shared ${LIB}_debug-shared) + set( THIS_LIBRARY_SEARCH_RELEASE ${LIB} ${LIB}-shared) + endif() + find_library(HDF5_${LIB}_LIBRARY_DEBUG + NAMES ${THIS_LIBRARY_SEARCH_DEBUG} + HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib + ${_HDF5_SEARCH_OPTS} + ) + find_library( HDF5_${LIB}_LIBRARY_RELEASE + NAMES ${THIS_LIBRARY_SEARCH_RELEASE} + HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib + ${_HDF5_SEARCH_OPTS} + ) + select_library_configurations( HDF5_${LIB} ) + list(APPEND HDF5_${__lang}_HL_LIBRARIES ${HDF5_${LIB}_LIBRARY}) + endforeach() + + # Append the libraries for this language binding to the list of all + # required libraries. + list(APPEND HDF5_HL_LIBRARIES ${HDF5_${__lang}_HL_LIBRARIES}) + endif() + endforeach() + if(FIND_HL AND HDF5_HL_LIBRARIES) + set(HDF5_HL_FOUND True) + endif() + + _HDF5_remove_duplicates_from_beginning(HDF5_DEFINITIONS) + _HDF5_remove_duplicates_from_beginning(HDF5_INCLUDE_DIRS) + _HDF5_remove_duplicates_from_beginning(HDF5_LIBRARIES) + _HDF5_remove_duplicates_from_beginning(HDF5_HL_LIBRARIES) + + # If the HDF5 include directory was found, open H5pubconf.h to determine if + # HDF5 was compiled with parallel IO support + set( HDF5_IS_PARALLEL FALSE ) + set( HDF5_VERSION "" ) + foreach( _dir IN LISTS HDF5_INCLUDE_DIRS ) + foreach(_hdr "${_dir}/H5pubconf.h" "${_dir}/H5pubconf-64.h" "${_dir}/H5pubconf-32.h") + if( EXISTS "${_hdr}" ) + file( STRINGS "${_hdr}" + HDF5_HAVE_PARALLEL_DEFINE + REGEX "HAVE_PARALLEL 1" ) + if( HDF5_HAVE_PARALLEL_DEFINE ) + set( HDF5_IS_PARALLEL TRUE ) + endif() + unset(HDF5_HAVE_PARALLEL_DEFINE) + + file( STRINGS "${_hdr}" + HDF5_VERSION_DEFINE + REGEX "^[ \t]*#[ \t]*define[ \t]+H5_VERSION[ \t]+" ) + if( "${HDF5_VERSION_DEFINE}" MATCHES + "H5_VERSION[ \t]+\"([0-9]+\\.[0-9]+\\.[0-9]+)(-patch([0-9]+))?\"" ) + set( HDF5_VERSION "${CMAKE_MATCH_1}" ) + if( CMAKE_MATCH_3 ) + set( HDF5_VERSION ${HDF5_VERSION}.${CMAKE_MATCH_3}) + endif() + endif() + unset(HDF5_VERSION_DEFINE) + endif() + endforeach() + endforeach() + set( HDF5_IS_PARALLEL ${HDF5_IS_PARALLEL} CACHE BOOL + "HDF5 library compiled with parallel IO support" ) + mark_as_advanced( HDF5_IS_PARALLEL ) + + set(HDF5_REQUIRED_VARS HDF5_LIBRARIES HDF5_INCLUDE_DIRS) + if(FIND_HL) + list(APPEND HDF5_REQUIRED_VARS HDF5_HL_LIBRARIES) + endif() +endif() + +# For backwards compatibility we set HDF5_INCLUDE_DIR to the value of +# HDF5_INCLUDE_DIRS +if( HDF5_INCLUDE_DIRS ) + set( HDF5_INCLUDE_DIR "${HDF5_INCLUDE_DIRS}" ) +endif() + +# If HDF5_REQUIRED_VARS is empty at this point, then it's likely that +# something external is trying to explicitly pass already found +# locations +if(NOT HDF5_REQUIRED_VARS) + set(HDF5_REQUIRED_VARS HDF5_LIBRARIES HDF5_INCLUDE_DIRS) +endif() + +find_package_handle_standard_args(HDF5 + REQUIRED_VARS ${HDF5_REQUIRED_VARS} + VERSION_VAR HDF5_VERSION + HANDLE_COMPONENTS +) + +unset(_HDF5_SEARCH_OPTS) + +if( HDF5_FOUND AND NOT HDF5_DIR) + # hide HDF5_DIR for the non-advanced user to avoid confusion with + # HDF5_DIR-NOT_FOUND while HDF5 was found. + mark_as_advanced(HDF5_DIR) +endif() + +if (HDF5_FIND_DEBUG) + message(STATUS "HDF5_DIR: ${HDF5_DIR}") + message(STATUS "HDF5_DEFINITIONS: ${HDF5_DEFINITIONS}") + message(STATUS "HDF5_INCLUDE_DIRS: ${HDF5_INCLUDE_DIRS}") + message(STATUS "HDF5_LIBRARIES: ${HDF5_LIBRARIES}") + message(STATUS "HDF5_HL_LIBRARIES: ${HDF5_HL_LIBRARIES}") + foreach(__lang IN LISTS HDF5_LANGUAGE_BINDINGS) + message(STATUS "HDF5_${__lang}_DEFINITIONS: ${HDF5_${__lang}_DEFINITIONS}") + message(STATUS "HDF5_${__lang}_INCLUDE_DIR: ${HDF5_${__lang}_INCLUDE_DIR}") + message(STATUS "HDF5_${__lang}_INCLUDE_DIRS: ${HDF5_${__lang}_INCLUDE_DIRS}") + message(STATUS "HDF5_${__lang}_LIBRARY: ${HDF5_${__lang}_LIBRARY}") + message(STATUS "HDF5_${__lang}_LIBRARIES: ${HDF5_${__lang}_LIBRARIES}") + message(STATUS "HDF5_${__lang}_HL_LIBRARY: ${HDF5_${__lang}_HL_LIBRARY}") + message(STATUS "HDF5_${__lang}_HL_LIBRARIES: ${HDF5_${__lang}_HL_LIBRARIES}") + endforeach() +endif() diff --git a/Kommon/cmake/FindLOG4CXX.cmake b/Kommon/cmake/FindLOG4CXX.cmake new file mode 100644 index 000000000..9f66020d0 --- /dev/null +++ b/Kommon/cmake/FindLOG4CXX.cmake @@ -0,0 +1,60 @@ +# $Id$ +################################################################################ +# +# CMake script for finding Log4cxx. +# The default CMake search process is used to locate files. +# +# This script creates the following variables: +# LOG4CXX_FOUND: Boolean that indicates if the package was found +# LOG4CXX_INCLUDE_DIRS: Paths to the necessary header files +# LOG4CXX_LIBRARIES: Package libraries +# LOG4CXX_LIBRARY_DIRS: Path to package libraries +# +################################################################################ + +include(FindPackageHandleStandardArgs) + +# See if LOG4CXX_ROOT is not already set in CMake +IF (NOT LOG4CXX_ROOT) + # See if LOG4CXX_ROOT is set in process environment + IF ( NOT $ENV{LOG4CXX_ROOT} STREQUAL "" ) + SET (LOG4CXX_ROOT "$ENV{LOG4CXX_ROOT}") + MESSAGE(STATUS "Detected LOG4CXX_ROOT set to '${LOG4CXX_ROOT}'") + ENDIF () +ENDIF () + +# If LOG4CXX_ROOT is available, set up our hints +IF (LOG4CXX_ROOT) + SET (LOG4CXX_INCLUDE_HINTS HINTS "${LOG4CXX_ROOT}/include" "${LOG4CXX_ROOT}") + SET (LOG4CXX_LIBRARY_HINTS HINTS "${LOG4CXX_ROOT}/lib") +ENDIF () + +# Find headers and libraries +find_path(LOG4CXX_INCLUDE_DIR NAMES log4cxx/log4cxx.h ${LOG4CXX_INCLUDE_HINTS}) +find_library(LOG4CXX_LIBRARY NAMES log4cxx ${LOG4CXX_LIBRARY_HINTS}) +find_library(LOG4CXXD_LIBRARY NAMES log4cxx${CMAKE_DEBUG_POSTFIX} ${LOG4CXX_LIBRARY_HINTS}) + +# Set LOG4CXX_FOUND honoring the QUIET and REQUIRED arguments +find_package_handle_standard_args(LOG4CXX DEFAULT_MSG LOG4CXX_LIBRARY LOG4CXX_INCLUDE_DIR) + +# Output variables +if(LOG4CXX_FOUND) + # Include dirs + set(LOG4CXX_INCLUDE_DIRS ${LOG4CXX_INCLUDE_DIR}) + + # Libraries + if(LOG4CXX_LIBRARY) + set(LOG4CXX_LIBRARIES optimized ${LOG4CXX_LIBRARY}) + else(LOG4CXX_LIBRARY) + set(LOG4CXX_LIBRARIES "") + endif(LOG4CXX_LIBRARY) + if(LOG4CXXD_LIBRARY) + set(LOG4CXX_LIBRARIES debug ${LOG4CXXD_LIBRARY} ${LOG4CXX_LIBRARIES}) + endif(LOG4CXXD_LIBRARY) + + # Link dirs + get_filename_component(LOG4CXX_LIBRARY_DIRS ${LOG4CXX_LIBRARY} PATH) +endif() + +# Advanced options for not cluttering the cmake UIs +mark_as_advanced(LOG4CXX_INCLUDE_DIR LOG4CXX_LIBRARY LOG4CXXD_LIBRARY) diff --git a/Kommon/cmake/FindLibXml2.cmake b/Kommon/cmake/FindLibXml2.cmake new file mode 100644 index 000000000..47c0e7907 --- /dev/null +++ b/Kommon/cmake/FindLibXml2.cmake @@ -0,0 +1,102 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindLibXml2 +----------- + +Find the XML processing library (libxml2). + +IMPORTED Targets +^^^^^^^^^^^^^^^^ + +This module defines :prop_tgt:`IMPORTED` target ``LibXml2::LibXml2``, if +libxml2 has been found. + +Result variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables in your project: + +``LibXml2_FOUND`` + true if libxml2 headers and libraries were found +``LIBXML2_INCLUDE_DIR`` + the directory containing LibXml2 headers +``LIBXML2_INCLUDE_DIRS`` + list of the include directories needed to use LibXml2 +``LIBXML2_LIBRARIES`` + LibXml2 libraries to be linked +``LIBXML2_DEFINITIONS`` + the compiler switches required for using LibXml2 +``LIBXML2_XMLLINT_EXECUTABLE`` + path to the XML checking tool xmllint coming with LibXml2 +``LIBXML2_VERSION_STRING`` + the version of LibXml2 found (since CMake 2.8.8) + +Cache variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: + +``LIBXML2_INCLUDE_DIR`` + the directory containing LibXml2 headers +``LIBXML2_LIBRARY`` + path to the LibXml2 library +#]=======================================================================] + +# use pkg-config to get the directories and then use these values +# in the find_path() and find_library() calls +find_package(PkgConfig QUIET) +PKG_CHECK_MODULES(PC_LIBXML QUIET libxml-2.0) +set(LIBXML2_DEFINITIONS ${PC_LIBXML_CFLAGS_OTHER}) + +find_path(LIBXML2_INCLUDE_DIR NAMES libxml/xpath.h + HINTS + ${PC_LIBXML_INCLUDEDIR} + ${PC_LIBXML_INCLUDE_DIRS} + PATH_SUFFIXES libxml2 + ) + +# CMake 3.9 and below used 'LIBXML2_LIBRARIES' as the name of +# the cache entry storing the find_library result. Use the +# value if it was set by the project or user. +if(DEFINED LIBXML2_LIBRARIES AND NOT DEFINED LIBXML2_LIBRARY) + set(LIBXML2_LIBRARY ${LIBXML2_LIBRARIES}) +endif() + +find_library(LIBXML2_LIBRARY NAMES xml2 libxml2 + HINTS + ${PC_LIBXML_LIBDIR} + ${PC_LIBXML_LIBRARY_DIRS} + ) + +find_program(LIBXML2_XMLLINT_EXECUTABLE xmllint) +# for backwards compat. with KDE 4.0.x: +set(XMLLINT_EXECUTABLE "${LIBXML2_XMLLINT_EXECUTABLE}") + +if(PC_LIBXML_VERSION) + set(LIBXML2_VERSION_STRING ${PC_LIBXML_VERSION}) +elseif(LIBXML2_INCLUDE_DIR AND EXISTS "${LIBXML2_INCLUDE_DIR}/libxml/xmlversion.h") + file(STRINGS "${LIBXML2_INCLUDE_DIR}/libxml/xmlversion.h" libxml2_version_str + REGEX "^#define[\t ]+LIBXML_DOTTED_VERSION[\t ]+\".*\"") + + string(REGEX REPLACE "^#define[\t ]+LIBXML_DOTTED_VERSION[\t ]+\"([^\"]*)\".*" "\\1" + LIBXML2_VERSION_STRING "${libxml2_version_str}") + unset(libxml2_version_str) +endif() + +set(LIBXML2_INCLUDE_DIRS ${LIBXML2_INCLUDE_DIR} ${PC_LIBXML_INCLUDE_DIRS}) +set(LIBXML2_LIBRARIES ${LIBXML2_LIBRARY}) + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 + REQUIRED_VARS LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR + VERSION_VAR LIBXML2_VERSION_STRING) + +mark_as_advanced(LIBXML2_INCLUDE_DIR LIBXML2_LIBRARY LIBXML2_XMLLINT_EXECUTABLE) + +if(LibXml2_FOUND AND NOT TARGET LibXml2::LibXml2) + add_library(LibXml2::LibXml2 UNKNOWN IMPORTED) + set_target_properties(LibXml2::LibXml2 PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LIBXML2_INCLUDE_DIRS}") + set_property(TARGET LibXml2::LibXml2 APPEND PROPERTY IMPORTED_LOCATION "${LIBXML2_LIBRARY}") +endif() diff --git a/Kommon/cmake/FindMPI.cmake b/Kommon/cmake/FindMPI.cmake index b94e69eac..8c45a8c5f 100644 --- a/Kommon/cmake/FindMPI.cmake +++ b/Kommon/cmake/FindMPI.cmake @@ -1,247 +1,248 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -#.rst: -# FindMPI -# ------- -# -# Find a Message Passing Interface (MPI) implementation. -# -# The Message Passing Interface (MPI) is a library used to write -# high-performance distributed-memory parallel applications, and is -# typically deployed on a cluster. MPI is a standard interface (defined -# by the MPI forum) for which many implementations are available. -# -# Variables for using MPI -# ^^^^^^^^^^^^^^^^^^^^^^^ -# -# The module exposes the components ``C``, ``CXX``, ``MPICXX`` and ``Fortran``. -# Each of these controls the various MPI languages to search for. -# The difference between ``CXX`` and ``MPICXX`` is that ``CXX`` refers to the -# MPI C API being usable from C++, whereas ``MPICXX`` refers to the MPI-2 C++ API -# that was removed again in MPI-3. -# -# Depending on the enabled components the following variables will be set: -# -# ``MPI_FOUND`` -# Variable indicating that MPI settings for all requested languages have been found. -# If no components are specified, this is true if MPI settings for all enabled languages -# were detected. Note that the ``MPICXX`` component does not affect this variable. -# ``MPI_VERSION`` -# Minimal version of MPI detected among the requested languages, or all enabled languages -# if no components were specified. -# -# This module will set the following variables per language in your -# project, where ```` is one of C, CXX, or Fortran: -# -# ``MPI__FOUND`` -# Variable indicating the MPI settings for ```` were found and that -# simple MPI test programs compile with the provided settings. -# ``MPI__COMPILER`` -# MPI compiler for ```` if such a program exists. -# ``MPI__COMPILE_OPTIONS`` -# Compilation options for MPI programs in ````, given as a :ref:`;-list `. -# ``MPI__COMPILE_DEFINITIONS`` -# Compilation definitions for MPI programs in ````, given as a :ref:`;-list `. -# ``MPI__INCLUDE_DIRS`` -# Include path(s) for MPI header. -# ``MPI__LINK_FLAGS`` -# Linker flags for MPI programs. -# ``MPI__LIBRARIES`` -# All libraries to link MPI programs against. -# -# Additionally, the following :prop_tgt:`IMPORTED` targets are defined: -# -# ``MPI::MPI_`` -# Target for using MPI from ````. -# -# The following variables indicating which bindings are present will be defined: -# -# ``MPI_MPICXX_FOUND`` -# Variable indicating whether the MPI-2 C++ bindings are present (introduced in MPI-2, removed with MPI-3). -# ``MPI_Fortran_HAVE_F77_HEADER`` -# True if the Fortran 77 header ``mpif.h`` is available. -# ``MPI_Fortran_HAVE_F90_MODULE`` -# True if the Fortran 90 module ``mpi`` can be used for accessing MPI (MPI-2 and higher only). -# ``MPI_Fortran_HAVE_F08_MODULE`` -# True if the Fortran 2008 ``mpi_f08`` is available to MPI programs (MPI-3 and higher only). -# -# If possible, the MPI version will be determined by this module. The facilities to detect the MPI version -# were introduced with MPI-1.2, and therefore cannot be found for older MPI versions. -# -# ``MPI__VERSION_MAJOR`` -# Major version of MPI implemented for ```` by the MPI distribution. -# ``MPI__VERSION_MINOR`` -# Minor version of MPI implemented for ```` by the MPI distribution. -# ``MPI__VERSION`` -# MPI version implemented for ```` by the MPI distribution. -# -# Note that there's no variable for the C bindings being accessible through ``mpi.h``, since the MPI standards -# always have required this binding to work in both C and C++ code. -# -# For running MPI programs, the module sets the following variables -# -# ``MPIEXEC_EXECUTABLE`` -# Executable for running MPI programs, if such exists. -# ``MPIEXEC_NUMPROC_FLAG`` -# Flag to pass to ``mpiexec`` before giving it the number of processors to run on. -# ``MPIEXEC_MAX_NUMPROCS`` -# Number of MPI processors to utilize. Defaults to the number -# of processors detected on the host system. -# ``MPIEXEC_PREFLAGS`` -# Flags to pass to ``mpiexec`` directly before the executable to run. -# ``MPIEXEC_POSTFLAGS`` -# Flags to pass to ``mpiexec`` after other flags. -# -# Variables for locating MPI -# ^^^^^^^^^^^^^^^^^^^^^^^^^^ -# -# This module performs a three step search for an MPI implementation: -# -# 1. Check if the compiler has MPI support built-in. This is the case if the user passed a -# compiler wrapper as ``CMAKE__COMPILER`` or if they're on a Cray system. -# 2. Attempt to find an MPI compiler wrapper and determine the compiler information from it. -# 3. Try to find an MPI implementation that does not ship such a wrapper by guessing settings. -# Currently, only Microsoft MPI and MPICH2 on Windows are supported. -# -# For controlling the second step, the following variables may be set: -# -# ``MPI__COMPILER`` -# Search for the specified compiler wrapper and use it. -# ``MPI__COMPILER_FLAGS`` -# Flags to pass to the MPI compiler wrapper during interrogation. Some compiler wrappers -# support linking debug or tracing libraries if a specific flag is passed and this variable -# may be used to obtain them. -# ``MPI_COMPILER_FLAGS`` -# Used to initialize ``MPI__COMPILER_FLAGS`` if no language specific flag has been given. -# Empty by default. -# ``MPI_EXECUTABLE_SUFFIX`` -# A suffix which is appended to all names that are being looked for. For instance you may set this -# to ``.mpich`` or ``.openmpi`` to prefer the one or the other on Debian and its derivatives. -# -# In order to control the guessing step, the following variable may be set: -# -# ``MPI_GUESS_LIBRARY_NAME`` -# Valid values are ``MSMPI`` and ``MPICH2``. If set, only the given library will be searched for. -# By default, ``MSMPI`` will be preferred over ``MPICH2`` if both are available. -# This also sets ``MPI_SKIP_COMPILER_WRAPPER`` to ``true``, which may be overridden. -# -# Each of the search steps may be skipped with the following control variables: -# -# ``MPI_ASSUME_NO_BUILTIN_MPI`` -# If true, the module assumes that the compiler itself does not provide an MPI implementation and -# skips to step 2. -# ``MPI_SKIP_COMPILER_WRAPPER`` -# If true, no compiler wrapper will be searched for. -# ``MPI_SKIP_GUESSING`` -# If true, the guessing step will be skipped. -# -# Additionally, the following control variable is available to change search behavior: -# -# ``MPI_CXX_SKIP_MPICXX`` -# Add some definitions that will disable the MPI-2 C++ bindings. -# Currently supported are MPICH, Open MPI, Platform MPI and derivatives thereof, -# for example MVAPICH or Intel MPI. -# -# If the find procedure fails for a variable ``MPI__WORKS``, then the settings detected by or passed to -# the module did not work and even a simple MPI test program failed to compile. -# -# If all of these parameters were not sufficient to find the right MPI implementation, a user may -# disable the entire autodetection process by specifying both a list of libraries in ``MPI__LIBRARIES`` -# and a list of include directories in ``MPI__ADDITIONAL_INCLUDE_DIRS``. -# Any other variable may be set in addition to these two. The module will then validate the MPI settings and store the -# settings in the cache. -# -# Cache variables for MPI -# ^^^^^^^^^^^^^^^^^^^^^^^ -# -# The variable ``MPI__INCLUDE_DIRS`` will be assembled from the following variables. -# For C and CXX: -# -# ``MPI__HEADER_DIR`` -# Location of the ``mpi.h`` header on disk. -# -# For Fortran: -# -# ``MPI_Fortran_F77_HEADER_DIR`` -# Location of the Fortran 77 header ``mpif.h``, if it exists. -# ``MPI_Fortran_MODULE_DIR`` -# Location of the ``mpi`` or ``mpi_f08`` modules, if available. -# -# For all languages the following variables are additionally considered: -# -# ``MPI__ADDITIONAL_INCLUDE_DIRS`` -# A :ref:`;-list ` of paths needed in addition to the normal include directories. -# ``MPI__INCLUDE_DIR`` -# Path variables for include folders referred to by ````. -# ``MPI__ADDITIONAL_INCLUDE_VARS`` -# A :ref:`;-list ` of ```` that will be added to the include locations of ````. -# -# The variable ``MPI__LIBRARIES`` will be assembled from the following variables: -# -# ``MPI__LIBRARY`` -# The location of a library called ```` for use with MPI. -# ``MPI__LIB_NAMES`` -# A :ref:`;-list ` of ```` that will be added to the include locations of ````. -# -# Usage of mpiexec -# ^^^^^^^^^^^^^^^^ -# -# When using ``MPIEXEC_EXECUTABLE`` to execute MPI applications, you should typically -# use all of the ``MPIEXEC_EXECUTABLE`` flags as follows: -# -# :: -# -# ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} -# ${MPIEXEC_PREFLAGS} EXECUTABLE ${MPIEXEC_POSTFLAGS} ARGS -# -# where ``EXECUTABLE`` is the MPI program, and ``ARGS`` are the arguments to -# pass to the MPI program. -# -# Advanced variables for using MPI -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -# -# The module can perform some advanced feature detections upon explicit request. -# -# **Important notice:** The following checks cannot be performed without *executing* an MPI test program. -# Consider the special considerations for the behavior of :command:`try_run` during cross compilation. -# Moreover, running an MPI program can cause additional issues, like a firewall notification on some systems. -# You should only enable these detections if you absolutely need the information. -# -# If the following variables are set to true, the respective search will be performed: -# -# ``MPI_DETERMINE_Fortran_CAPABILITIES`` -# Determine for all available Fortran bindings what the values of ``MPI_SUBARRAYS_SUPPORTED`` and -# ``MPI_ASYNC_PROTECTS_NONBLOCKING`` are and make their values available as ``MPI_Fortran__SUBARRAYS`` -# and ``MPI_Fortran__ASYNCPROT``, where ```` is one of ``F77_HEADER``, ``F90_MODULE`` and -# ``F08_MODULE``. -# ``MPI_DETERMINE_LIBRARY_VERSION`` -# For each language, find the output of ``MPI_Get_library_version`` and make it available as ``MPI__LIBRARY_VERSION``. -# This information is usually tied to the runtime component of an MPI implementation and might differ depending on ````. -# Note that the return value is entirely implementation defined. This information might be used to identify -# the MPI vendor and for example pick the correct one of multiple third party binaries that matches the MPI vendor. -# -# Backward Compatibility -# ^^^^^^^^^^^^^^^^^^^^^^ -# -# For backward compatibility with older versions of FindMPI, these -# variables are set, but deprecated: -# -# :: -# -# MPI_COMPILER MPI_LIBRARY MPI_EXTRA_LIBRARY -# MPI_COMPILE_FLAGS MPI_INCLUDE_PATH MPI_LINK_FLAGS -# MPI_LIBRARIES -# -# In new projects, please use the ``MPI__XXX`` equivalents. -# Additionally, the following variables are deprecated: -# -# ``MPI__COMPILE_FLAGS`` -# Use ``MPI__COMPILE_OPTIONS`` and ``MPI__COMPILE_DEFINITIONS`` instead. -# ``MPI__INCLUDE_PATH`` -# For consumption use ``MPI__INCLUDE_DIRS`` and for specifying folders use ``MPI__ADDITIONAL_INCLUDE_DIRS`` instead. -# ``MPIEXEC`` -# Use ``MPIEXEC_EXECUTABLE`` instead. +#[=======================================================================[.rst: +FindMPI +------- + +Find a Message Passing Interface (MPI) implementation. + +The Message Passing Interface (MPI) is a library used to write +high-performance distributed-memory parallel applications, and is +typically deployed on a cluster. MPI is a standard interface (defined +by the MPI forum) for which many implementations are available. + +Variables for using MPI +^^^^^^^^^^^^^^^^^^^^^^^ + +The module exposes the components ``C``, ``CXX``, ``MPICXX`` and ``Fortran``. +Each of these controls the various MPI languages to search for. +The difference between ``CXX`` and ``MPICXX`` is that ``CXX`` refers to the +MPI C API being usable from C++, whereas ``MPICXX`` refers to the MPI-2 C++ API +that was removed again in MPI-3. + +Depending on the enabled components the following variables will be set: + +``MPI_FOUND`` + Variable indicating that MPI settings for all requested languages have been found. + If no components are specified, this is true if MPI settings for all enabled languages + were detected. Note that the ``MPICXX`` component does not affect this variable. +``MPI_VERSION`` + Minimal version of MPI detected among the requested languages, or all enabled languages + if no components were specified. + +This module will set the following variables per language in your +project, where ```` is one of C, CXX, or Fortran: + +``MPI__FOUND`` + Variable indicating the MPI settings for ```` were found and that + simple MPI test programs compile with the provided settings. +``MPI__COMPILER`` + MPI compiler for ```` if such a program exists. +``MPI__COMPILE_OPTIONS`` + Compilation options for MPI programs in ````, given as a :ref:`;-list `. +``MPI__COMPILE_DEFINITIONS`` + Compilation definitions for MPI programs in ````, given as a :ref:`;-list `. +``MPI__INCLUDE_DIRS`` + Include path(s) for MPI header. +``MPI__LINK_FLAGS`` + Linker flags for MPI programs. +``MPI__LIBRARIES`` + All libraries to link MPI programs against. + +Additionally, the following :prop_tgt:`IMPORTED` targets are defined: + +``MPI::MPI_`` + Target for using MPI from ````. + +The following variables indicating which bindings are present will be defined: + +``MPI_MPICXX_FOUND`` + Variable indicating whether the MPI-2 C++ bindings are present (introduced in MPI-2, removed with MPI-3). +``MPI_Fortran_HAVE_F77_HEADER`` + True if the Fortran 77 header ``mpif.h`` is available. +``MPI_Fortran_HAVE_F90_MODULE`` + True if the Fortran 90 module ``mpi`` can be used for accessing MPI (MPI-2 and higher only). +``MPI_Fortran_HAVE_F08_MODULE`` + True if the Fortran 2008 ``mpi_f08`` is available to MPI programs (MPI-3 and higher only). + +If possible, the MPI version will be determined by this module. The facilities to detect the MPI version +were introduced with MPI-1.2, and therefore cannot be found for older MPI versions. + +``MPI__VERSION_MAJOR`` + Major version of MPI implemented for ```` by the MPI distribution. +``MPI__VERSION_MINOR`` + Minor version of MPI implemented for ```` by the MPI distribution. +``MPI__VERSION`` + MPI version implemented for ```` by the MPI distribution. + +Note that there's no variable for the C bindings being accessible through ``mpi.h``, since the MPI standards +always have required this binding to work in both C and C++ code. + +For running MPI programs, the module sets the following variables + +``MPIEXEC_EXECUTABLE`` + Executable for running MPI programs, if such exists. +``MPIEXEC_NUMPROC_FLAG`` + Flag to pass to ``mpiexec`` before giving it the number of processors to run on. +``MPIEXEC_MAX_NUMPROCS`` + Number of MPI processors to utilize. Defaults to the number + of processors detected on the host system. +``MPIEXEC_PREFLAGS`` + Flags to pass to ``mpiexec`` directly before the executable to run. +``MPIEXEC_POSTFLAGS`` + Flags to pass to ``mpiexec`` after other flags. + +Variables for locating MPI +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This module performs a three step search for an MPI implementation: + +1. Check if the compiler has MPI support built-in. This is the case if the user passed a + compiler wrapper as ``CMAKE__COMPILER`` or if they're on a Cray system. +2. Attempt to find an MPI compiler wrapper and determine the compiler information from it. +3. Try to find an MPI implementation that does not ship such a wrapper by guessing settings. + Currently, only Microsoft MPI and MPICH2 on Windows are supported. + +For controlling the second step, the following variables may be set: + +``MPI__COMPILER`` + Search for the specified compiler wrapper and use it. +``MPI__COMPILER_FLAGS`` + Flags to pass to the MPI compiler wrapper during interrogation. Some compiler wrappers + support linking debug or tracing libraries if a specific flag is passed and this variable + may be used to obtain them. +``MPI_COMPILER_FLAGS`` + Used to initialize ``MPI__COMPILER_FLAGS`` if no language specific flag has been given. + Empty by default. +``MPI_EXECUTABLE_SUFFIX`` + A suffix which is appended to all names that are being looked for. For instance you may set this + to ``.mpich`` or ``.openmpi`` to prefer the one or the other on Debian and its derivatives. + +In order to control the guessing step, the following variable may be set: + +``MPI_GUESS_LIBRARY_NAME`` + Valid values are ``MSMPI`` and ``MPICH2``. If set, only the given library will be searched for. + By default, ``MSMPI`` will be preferred over ``MPICH2`` if both are available. + This also sets ``MPI_SKIP_COMPILER_WRAPPER`` to ``true``, which may be overridden. + +Each of the search steps may be skipped with the following control variables: + +``MPI_ASSUME_NO_BUILTIN_MPI`` + If true, the module assumes that the compiler itself does not provide an MPI implementation and + skips to step 2. +``MPI_SKIP_COMPILER_WRAPPER`` + If true, no compiler wrapper will be searched for. +``MPI_SKIP_GUESSING`` + If true, the guessing step will be skipped. + +Additionally, the following control variable is available to change search behavior: + +``MPI_CXX_SKIP_MPICXX`` + Add some definitions that will disable the MPI-2 C++ bindings. + Currently supported are MPICH, Open MPI, Platform MPI and derivatives thereof, + for example MVAPICH or Intel MPI. + +If the find procedure fails for a variable ``MPI__WORKS``, then the settings detected by or passed to +the module did not work and even a simple MPI test program failed to compile. + +If all of these parameters were not sufficient to find the right MPI implementation, a user may +disable the entire autodetection process by specifying both a list of libraries in ``MPI__LIBRARIES`` +and a list of include directories in ``MPI__ADDITIONAL_INCLUDE_DIRS``. +Any other variable may be set in addition to these two. The module will then validate the MPI settings and store the +settings in the cache. + +Cache variables for MPI +^^^^^^^^^^^^^^^^^^^^^^^ + +The variable ``MPI__INCLUDE_DIRS`` will be assembled from the following variables. +For C and CXX: + +``MPI__HEADER_DIR`` + Location of the ``mpi.h`` header on disk. + +For Fortran: + +``MPI_Fortran_F77_HEADER_DIR`` + Location of the Fortran 77 header ``mpif.h``, if it exists. +``MPI_Fortran_MODULE_DIR`` + Location of the ``mpi`` or ``mpi_f08`` modules, if available. + +For all languages the following variables are additionally considered: + +``MPI__ADDITIONAL_INCLUDE_DIRS`` + A :ref:`;-list ` of paths needed in addition to the normal include directories. +``MPI__INCLUDE_DIR`` + Path variables for include folders referred to by ````. +``MPI__ADDITIONAL_INCLUDE_VARS`` + A :ref:`;-list ` of ```` that will be added to the include locations of ````. + +The variable ``MPI__LIBRARIES`` will be assembled from the following variables: + +``MPI__LIBRARY`` + The location of a library called ```` for use with MPI. +``MPI__LIB_NAMES`` + A :ref:`;-list ` of ```` that will be added to the include locations of ````. + +Usage of mpiexec +^^^^^^^^^^^^^^^^ + +When using ``MPIEXEC_EXECUTABLE`` to execute MPI applications, you should typically +use all of the ``MPIEXEC_EXECUTABLE`` flags as follows: + +:: + + ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} + ${MPIEXEC_PREFLAGS} EXECUTABLE ${MPIEXEC_POSTFLAGS} ARGS + +where ``EXECUTABLE`` is the MPI program, and ``ARGS`` are the arguments to +pass to the MPI program. + +Advanced variables for using MPI +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The module can perform some advanced feature detections upon explicit request. + +**Important notice:** The following checks cannot be performed without *executing* an MPI test program. +Consider the special considerations for the behavior of :command:`try_run` during cross compilation. +Moreover, running an MPI program can cause additional issues, like a firewall notification on some systems. +You should only enable these detections if you absolutely need the information. + +If the following variables are set to true, the respective search will be performed: + +``MPI_DETERMINE_Fortran_CAPABILITIES`` + Determine for all available Fortran bindings what the values of ``MPI_SUBARRAYS_SUPPORTED`` and + ``MPI_ASYNC_PROTECTS_NONBLOCKING`` are and make their values available as ``MPI_Fortran__SUBARRAYS`` + and ``MPI_Fortran__ASYNCPROT``, where ```` is one of ``F77_HEADER``, ``F90_MODULE`` and + ``F08_MODULE``. +``MPI_DETERMINE_LIBRARY_VERSION`` + For each language, find the output of ``MPI_Get_library_version`` and make it available as ``MPI__LIBRARY_VERSION``. + This information is usually tied to the runtime component of an MPI implementation and might differ depending on ````. + Note that the return value is entirely implementation defined. This information might be used to identify + the MPI vendor and for example pick the correct one of multiple third party binaries that matches the MPI vendor. + +Backward Compatibility +^^^^^^^^^^^^^^^^^^^^^^ + +For backward compatibility with older versions of FindMPI, these +variables are set, but deprecated: + +:: + + MPI_COMPILER MPI_LIBRARY MPI_EXTRA_LIBRARY + MPI_COMPILE_FLAGS MPI_INCLUDE_PATH MPI_LINK_FLAGS + MPI_LIBRARIES + +In new projects, please use the ``MPI__XXX`` equivalents. +Additionally, the following variables are deprecated: + +``MPI__COMPILE_FLAGS`` + Use ``MPI__COMPILE_OPTIONS`` and ``MPI__COMPILE_DEFINITIONS`` instead. +``MPI__INCLUDE_PATH`` + For consumption use ``MPI__INCLUDE_DIRS`` and for specifying folders use ``MPI__ADDITIONAL_INCLUDE_DIRS`` instead. +``MPIEXEC`` + Use ``MPIEXEC_EXECUTABLE`` instead. +#]=======================================================================] cmake_policy(PUSH) cmake_policy(SET CMP0057 NEW) # if IN_LIST diff --git a/Kommon/cmake/FindOpenCL.cmake b/Kommon/cmake/FindOpenCL.cmake index fe162b49b..79c0382d3 100644 --- a/Kommon/cmake/FindOpenCL.cmake +++ b/Kommon/cmake/FindOpenCL.cmake @@ -1,35 +1,36 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -#.rst: -# FindOpenCL -# ---------- -# -# Try to find OpenCL -# -# IMPORTED Targets -# ^^^^^^^^^^^^^^^^ -# -# This module defines :prop_tgt:`IMPORTED` target ``OpenCL::OpenCL``, if -# OpenCL has been found. -# -# Result Variables -# ^^^^^^^^^^^^^^^^ -# -# This module defines the following variables:: -# -# OpenCL_FOUND - True if OpenCL was found -# OpenCL_INCLUDE_DIRS - include directories for OpenCL -# OpenCL_LIBRARIES - link against this library to use OpenCL -# OpenCL_VERSION_STRING - Highest supported OpenCL version (eg. 1.2) -# OpenCL_VERSION_MAJOR - The major version of the OpenCL implementation -# OpenCL_VERSION_MINOR - The minor version of the OpenCL implementation -# -# The module will also define two cache variables:: -# -# OpenCL_INCLUDE_DIR - the OpenCL include directory -# OpenCL_LIBRARY - the path to the OpenCL library -# +#[=======================================================================[.rst: +FindOpenCL +---------- + +Try to find OpenCL + +IMPORTED Targets +^^^^^^^^^^^^^^^^ + +This module defines :prop_tgt:`IMPORTED` target ``OpenCL::OpenCL``, if +OpenCL has been found. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module defines the following variables:: + + OpenCL_FOUND - True if OpenCL was found + OpenCL_INCLUDE_DIRS - include directories for OpenCL + OpenCL_LIBRARIES - link against this library to use OpenCL + OpenCL_VERSION_STRING - Highest supported OpenCL version (eg. 1.2) + OpenCL_VERSION_MAJOR - The major version of the OpenCL implementation + OpenCL_VERSION_MINOR - The minor version of the OpenCL implementation + +The module will also define two cache variables:: + + OpenCL_INCLUDE_DIR - the OpenCL include directory + OpenCL_LIBRARY - the path to the OpenCL library + +#]=======================================================================] function(_FIND_OPENCL_VERSION) include(CheckSymbolExists) diff --git a/Kommon/cmake/FindOpenMP.cmake b/Kommon/cmake/FindOpenMP.cmake index cbc6ed846..7e3721276 100644 --- a/Kommon/cmake/FindOpenMP.cmake +++ b/Kommon/cmake/FindOpenMP.cmake @@ -1,78 +1,79 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -#.rst: -# FindOpenMP -# ---------- -# -# Finds OpenMP support -# -# This module can be used to detect OpenMP support in a compiler. If -# the compiler supports OpenMP, the flags required to compile with -# OpenMP support are returned in variables for the different languages. -# The variables may be empty if the compiler does not need a special -# flag to support OpenMP. -# -# Variables -# ^^^^^^^^^ -# -# The module exposes the components ``C``, ``CXX``, and ``Fortran``. -# Each of these controls the various languages to search OpenMP support for. -# -# Depending on the enabled components the following variables will be set: -# -# ``OpenMP_FOUND`` -# Variable indicating that OpenMP flags for all requested languages have been found. -# If no components are specified, this is true if OpenMP settings for all enabled languages -# were detected. -# ``OpenMP_VERSION`` -# Minimal version of the OpenMP standard detected among the requested languages, -# or all enabled languages if no components were specified. -# -# This module will set the following variables per language in your -# project, where ```` is one of C, CXX, or Fortran: -# -# ``OpenMP__FOUND`` -# Variable indicating if OpenMP support for ```` was detected. -# ``OpenMP__FLAGS`` -# OpenMP compiler flags for ````, separated by spaces. -# -# For linking with OpenMP code written in ````, the following -# variables are provided: -# -# ``OpenMP__LIB_NAMES`` -# :ref:`;-list ` of libraries for OpenMP programs for ````. -# ``OpenMP__LIBRARY`` -# Location of the individual libraries needed for OpenMP support in ````. -# ``OpenMP__LIBRARIES`` -# A list of libraries needed to link with OpenMP code written in ````. -# -# Additionally, the module provides :prop_tgt:`IMPORTED` targets: -# -# ``OpenMP::OpenMP_`` -# Target for using OpenMP from ````. -# -# Specifically for Fortran, the module sets the following variables: -# -# ``OpenMP_Fortran_HAVE_OMPLIB_HEADER`` -# Boolean indicating if OpenMP is accessible through ``omp_lib.h``. -# ``OpenMP_Fortran_HAVE_OMPLIB_MODULE`` -# Boolean indicating if OpenMP is accessible through the ``omp_lib`` Fortran module. -# -# The module will also try to provide the OpenMP version variables: -# -# ``OpenMP__SPEC_DATE`` -# Date of the OpenMP specification implemented by the ```` compiler. -# ``OpenMP__VERSION_MAJOR`` -# Major version of OpenMP implemented by the ```` compiler. -# ``OpenMP__VERSION_MINOR`` -# Minor version of OpenMP implemented by the ```` compiler. -# ``OpenMP__VERSION`` -# OpenMP version implemented by the ```` compiler. -# -# The specification date is formatted as given in the OpenMP standard: -# ``yyyymm`` where ``yyyy`` and ``mm`` represents the year and month of -# the OpenMP specification implemented by the ```` compiler. +#[=======================================================================[.rst: +FindOpenMP +---------- + +Finds OpenMP support + +This module can be used to detect OpenMP support in a compiler. If +the compiler supports OpenMP, the flags required to compile with +OpenMP support are returned in variables for the different languages. +The variables may be empty if the compiler does not need a special +flag to support OpenMP. + +Variables +^^^^^^^^^ + +The module exposes the components ``C``, ``CXX``, and ``Fortran``. +Each of these controls the various languages to search OpenMP support for. + +Depending on the enabled components the following variables will be set: + +``OpenMP_FOUND`` + Variable indicating that OpenMP flags for all requested languages have been found. + If no components are specified, this is true if OpenMP settings for all enabled languages + were detected. +``OpenMP_VERSION`` + Minimal version of the OpenMP standard detected among the requested languages, + or all enabled languages if no components were specified. + +This module will set the following variables per language in your +project, where ```` is one of C, CXX, or Fortran: + +``OpenMP__FOUND`` + Variable indicating if OpenMP support for ```` was detected. +``OpenMP__FLAGS`` + OpenMP compiler flags for ````, separated by spaces. + +For linking with OpenMP code written in ````, the following +variables are provided: + +``OpenMP__LIB_NAMES`` + :ref:`;-list ` of libraries for OpenMP programs for ````. +``OpenMP__LIBRARY`` + Location of the individual libraries needed for OpenMP support in ````. +``OpenMP__LIBRARIES`` + A list of libraries needed to link with OpenMP code written in ````. + +Additionally, the module provides :prop_tgt:`IMPORTED` targets: + +``OpenMP::OpenMP_`` + Target for using OpenMP from ````. + +Specifically for Fortran, the module sets the following variables: + +``OpenMP_Fortran_HAVE_OMPLIB_HEADER`` + Boolean indicating if OpenMP is accessible through ``omp_lib.h``. +``OpenMP_Fortran_HAVE_OMPLIB_MODULE`` + Boolean indicating if OpenMP is accessible through the ``omp_lib`` Fortran module. + +The module will also try to provide the OpenMP version variables: + +``OpenMP__SPEC_DATE`` + Date of the OpenMP specification implemented by the ```` compiler. +``OpenMP__VERSION_MAJOR`` + Major version of OpenMP implemented by the ```` compiler. +``OpenMP__VERSION_MINOR`` + Minor version of OpenMP implemented by the ```` compiler. +``OpenMP__VERSION`` + OpenMP version implemented by the ```` compiler. + +The specification date is formatted as given in the OpenMP standard: +``yyyymm`` where ``yyyy`` and ``mm`` represents the year and month of +the OpenMP specification implemented by the ```` compiler. +#]=======================================================================] cmake_policy(PUSH) cmake_policy(SET CMP0012 NEW) # if() recognizes numbers and booleans diff --git a/Kommon/cmake/FindOpenSSL.cmake b/Kommon/cmake/FindOpenSSL.cmake new file mode 100644 index 000000000..5f947fe54 --- /dev/null +++ b/Kommon/cmake/FindOpenSSL.cmake @@ -0,0 +1,493 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindOpenSSL +----------- + +Find the OpenSSL encryption library. + +Optional COMPONENTS +^^^^^^^^^^^^^^^^^^^ + +This module supports two optional COMPONENTS: ``Crypto`` and ``SSL``. Both +components have associated imported targets, as described below. + +Imported Targets +^^^^^^^^^^^^^^^^ + +This module defines the following :prop_tgt:`IMPORTED` targets: + +``OpenSSL::SSL`` + The OpenSSL ``ssl`` library, if found. +``OpenSSL::Crypto`` + The OpenSSL ``crypto`` library, if found. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables in your project: + +``OPENSSL_FOUND`` + System has the OpenSSL library. If no components are requested it only + requires the crypto library. +``OPENSSL_INCLUDE_DIR`` + The OpenSSL include directory. +``OPENSSL_CRYPTO_LIBRARY`` + The OpenSSL crypto library. +``OPENSSL_SSL_LIBRARY`` + The OpenSSL SSL library. +``OPENSSL_LIBRARIES`` + All OpenSSL libraries. +``OPENSSL_VERSION`` + This is set to ``$major.$minor.$revision$patch`` (e.g. ``0.9.8s``). + +Hints +^^^^^ + +Set ``OPENSSL_ROOT_DIR`` to the root directory of an OpenSSL installation. +Set ``OPENSSL_USE_STATIC_LIBS`` to ``TRUE`` to look for static libraries. +Set ``OPENSSL_MSVC_STATIC_RT`` set ``TRUE`` to choose the MT version of the lib. +#]=======================================================================] + +if (UNIX) + find_package(PkgConfig QUIET) + pkg_check_modules(_OPENSSL QUIET openssl) +endif () + +# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES +if(OPENSSL_USE_STATIC_LIBS) + set(_openssl_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + if(WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ) + endif() +endif() + +if (WIN32) + # http://www.slproweb.com/products/Win32OpenSSL.html + set(_OPENSSL_ROOT_HINTS + ${OPENSSL_ROOT_DIR} + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;Inno Setup: App Path]" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;Inno Setup: App Path]" + ENV OPENSSL_ROOT_DIR + ) + file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" _programfiles) + set(_OPENSSL_ROOT_PATHS + "${_programfiles}/OpenSSL" + "${_programfiles}/OpenSSL-Win32" + "${_programfiles}/OpenSSL-Win64" + "C:/OpenSSL/" + "C:/OpenSSL-Win32/" + "C:/OpenSSL-Win64/" + ) + unset(_programfiles) +else () + set(_OPENSSL_ROOT_HINTS + ${OPENSSL_ROOT_DIR} + ENV OPENSSL_ROOT_DIR + ) +endif () + +set(_OPENSSL_ROOT_HINTS_AND_PATHS + HINTS ${_OPENSSL_ROOT_HINTS} + PATHS ${_OPENSSL_ROOT_PATHS} + ) + +find_path(OPENSSL_INCLUDE_DIR + NAMES + openssl/ssl.h + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + HINTS + ${_OPENSSL_INCLUDEDIR} + PATH_SUFFIXES + include +) + +if(WIN32 AND NOT CYGWIN) + if(MSVC) + # /MD and /MDd are the standard values - if someone wants to use + # others, the libnames have to change here too + # use also ssl and ssleay32 in debug as fallback for openssl < 0.9.8b + # enable OPENSSL_MSVC_STATIC_RT to get the libs build /MT (Multithreaded no-DLL) + # In Visual C++ naming convention each of these four kinds of Windows libraries has it's standard suffix: + # * MD for dynamic-release + # * MDd for dynamic-debug + # * MT for static-release + # * MTd for static-debug + + # Implementation details: + # We are using the libraries located in the VC subdir instead of the parent directory even though : + # libeay32MD.lib is identical to ../libeay32.lib, and + # ssleay32MD.lib is identical to ../ssleay32.lib + # enable OPENSSL_USE_STATIC_LIBS to use the static libs located in lib/VC/static + + if (OPENSSL_MSVC_STATIC_RT) + set(_OPENSSL_MSVC_RT_MODE "MT") + else () + set(_OPENSSL_MSVC_RT_MODE "MD") + endif () + + # Since OpenSSL 1.1, lib names are like libcrypto32MTd.lib and libssl32MTd.lib + if( "${CMAKE_SIZEOF_VOID_P}" STREQUAL "8" ) + set(_OPENSSL_MSVC_ARCH_SUFFIX "64") + else() + set(_OPENSSL_MSVC_ARCH_SUFFIX "32") + endif() + + if(OPENSSL_USE_STATIC_LIBS) + set(_OPENSSL_PATH_SUFFIXES + "lib/VC/static" + "VC/static" + "lib" + ) + else() + set(_OPENSSL_PATH_SUFFIXES + "lib/VC" + "VC" + "lib" + ) + endif () + + find_library(LIB_EAY_DEBUG + NAMES + libcrypto${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE}d + libcrypto${_OPENSSL_MSVC_RT_MODE}d + libcryptod + libeay32${_OPENSSL_MSVC_RT_MODE}d + libeay32d + cryptod + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + ${_OPENSSL_PATH_SUFFIXES} + ) + + find_library(LIB_EAY_RELEASE + NAMES + libcrypto${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE} + libcrypto${_OPENSSL_MSVC_RT_MODE} + libcrypto + libeay32${_OPENSSL_MSVC_RT_MODE} + libeay32 + crypto + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + ${_OPENSSL_PATH_SUFFIXES} + ) + + find_library(SSL_EAY_DEBUG + NAMES + libssl${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE}d + libssl${_OPENSSL_MSVC_RT_MODE}d + libssld + ssleay32${_OPENSSL_MSVC_RT_MODE}d + ssleay32d + ssld + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + ${_OPENSSL_PATH_SUFFIXES} + ) + + find_library(SSL_EAY_RELEASE + NAMES + libssl${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE} + libssl${_OPENSSL_MSVC_RT_MODE} + libssl + ssleay32${_OPENSSL_MSVC_RT_MODE} + ssleay32 + ssl + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + ${_OPENSSL_PATH_SUFFIXES} + ) + + set(LIB_EAY_LIBRARY_DEBUG "${LIB_EAY_DEBUG}") + set(LIB_EAY_LIBRARY_RELEASE "${LIB_EAY_RELEASE}") + set(SSL_EAY_LIBRARY_DEBUG "${SSL_EAY_DEBUG}") + set(SSL_EAY_LIBRARY_RELEASE "${SSL_EAY_RELEASE}") + + include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) + select_library_configurations(LIB_EAY) + select_library_configurations(SSL_EAY) + + mark_as_advanced(LIB_EAY_LIBRARY_DEBUG LIB_EAY_LIBRARY_RELEASE + SSL_EAY_LIBRARY_DEBUG SSL_EAY_LIBRARY_RELEASE) + set(OPENSSL_SSL_LIBRARY ${SSL_EAY_LIBRARY} ) + set(OPENSSL_CRYPTO_LIBRARY ${LIB_EAY_LIBRARY} ) + elseif(MINGW) + # same player, for MinGW + set(LIB_EAY_NAMES crypto libeay32) + set(SSL_EAY_NAMES ssl ssleay32) + find_library(LIB_EAY + NAMES + ${LIB_EAY_NAMES} + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + "lib/MinGW" + "lib" + ) + + find_library(SSL_EAY + NAMES + ${SSL_EAY_NAMES} + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + "lib/MinGW" + "lib" + ) + + mark_as_advanced(SSL_EAY LIB_EAY) + set(OPENSSL_SSL_LIBRARY ${SSL_EAY} ) + set(OPENSSL_CRYPTO_LIBRARY ${LIB_EAY} ) + unset(LIB_EAY_NAMES) + unset(SSL_EAY_NAMES) + else() + # Not sure what to pick for -say- intel, let's use the toplevel ones and hope someone report issues: + find_library(LIB_EAY + NAMES + libcrypto + libeay32 + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + HINTS + ${_OPENSSL_LIBDIR} + PATH_SUFFIXES + lib + ) + + find_library(SSL_EAY + NAMES + libssl + ssleay32 + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + HINTS + ${_OPENSSL_LIBDIR} + PATH_SUFFIXES + lib + ) + + mark_as_advanced(SSL_EAY LIB_EAY) + set(OPENSSL_SSL_LIBRARY ${SSL_EAY} ) + set(OPENSSL_CRYPTO_LIBRARY ${LIB_EAY} ) + endif() +else() + + find_library(OPENSSL_SSL_LIBRARY + NAMES + ssl + ssleay32 + ssleay32MD + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + HINTS + ${_OPENSSL_LIBDIR} + PATH_SUFFIXES + lib + ) + + find_library(OPENSSL_CRYPTO_LIBRARY + NAMES + crypto + NAMES_PER_DIR + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + HINTS + ${_OPENSSL_LIBDIR} + PATH_SUFFIXES + lib + ) + + mark_as_advanced(OPENSSL_CRYPTO_LIBRARY OPENSSL_SSL_LIBRARY) + + # compat defines + set(OPENSSL_SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY}) + set(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY}) + +endif() + +function(from_hex HEX DEC) + string(TOUPPER "${HEX}" HEX) + set(_res 0) + string(LENGTH "${HEX}" _strlen) + + while (_strlen GREATER 0) + math(EXPR _res "${_res} * 16") + string(SUBSTRING "${HEX}" 0 1 NIBBLE) + string(SUBSTRING "${HEX}" 1 -1 HEX) + if (NIBBLE STREQUAL "A") + math(EXPR _res "${_res} + 10") + elseif (NIBBLE STREQUAL "B") + math(EXPR _res "${_res} + 11") + elseif (NIBBLE STREQUAL "C") + math(EXPR _res "${_res} + 12") + elseif (NIBBLE STREQUAL "D") + math(EXPR _res "${_res} + 13") + elseif (NIBBLE STREQUAL "E") + math(EXPR _res "${_res} + 14") + elseif (NIBBLE STREQUAL "F") + math(EXPR _res "${_res} + 15") + else() + math(EXPR _res "${_res} + ${NIBBLE}") + endif() + + string(LENGTH "${HEX}" _strlen) + endwhile() + + set(${DEC} ${_res} PARENT_SCOPE) +endfunction() + +if(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h") + file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" openssl_version_str + REGEX "^#[\t ]*define[\t ]+OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])+.*") + + if(openssl_version_str) + # The version number is encoded as 0xMNNFFPPS: major minor fix patch status + # The status gives if this is a developer or prerelease and is ignored here. + # Major, minor, and fix directly translate into the version numbers shown in + # the string. The patch field translates to the single character suffix that + # indicates the bug fix state, which 00 -> nothing, 01 -> a, 02 -> b and so + # on. + + string(REGEX REPLACE "^.*OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F]).*$" + "\\1;\\2;\\3;\\4;\\5" OPENSSL_VERSION_LIST "${openssl_version_str}") + list(GET OPENSSL_VERSION_LIST 0 OPENSSL_VERSION_MAJOR) + list(GET OPENSSL_VERSION_LIST 1 OPENSSL_VERSION_MINOR) + from_hex("${OPENSSL_VERSION_MINOR}" OPENSSL_VERSION_MINOR) + list(GET OPENSSL_VERSION_LIST 2 OPENSSL_VERSION_FIX) + from_hex("${OPENSSL_VERSION_FIX}" OPENSSL_VERSION_FIX) + list(GET OPENSSL_VERSION_LIST 3 OPENSSL_VERSION_PATCH) + + if (NOT OPENSSL_VERSION_PATCH STREQUAL "00") + from_hex("${OPENSSL_VERSION_PATCH}" _tmp) + # 96 is the ASCII code of 'a' minus 1 + math(EXPR OPENSSL_VERSION_PATCH_ASCII "${_tmp} + 96") + unset(_tmp) + # Once anyone knows how OpenSSL would call the patch versions beyond 'z' + # this should be updated to handle that, too. This has not happened yet + # so it is simply ignored here for now. + string(ASCII "${OPENSSL_VERSION_PATCH_ASCII}" OPENSSL_VERSION_PATCH_STRING) + endif () + + set(OPENSSL_VERSION "${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MINOR}.${OPENSSL_VERSION_FIX}${OPENSSL_VERSION_PATCH_STRING}") + endif () +endif () + +set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY} ) + +foreach(_comp IN LISTS OpenSSL_FIND_COMPONENTS) + if(_comp STREQUAL "Crypto") + if(EXISTS "${OPENSSL_INCLUDE_DIR}" AND + (EXISTS "${OPENSSL_CRYPTO_LIBRARY}" OR + EXISTS "${LIB_EAY_LIBRARY_DEBUG}" OR + EXISTS "${LIB_EAY_LIBRARY_RELEASE}") + ) + set(OpenSSL_${_comp}_FOUND TRUE) + else() + set(OpenSSL_${_comp}_FOUND FALSE) + endif() + elseif(_comp STREQUAL "SSL") + if(EXISTS "${OPENSSL_INCLUDE_DIR}" AND + (EXISTS "${OPENSSL_SSL_LIBRARY}" OR + EXISTS "${SSL_EAY_LIBRARY_DEBUG}" OR + EXISTS "${SSL_EAY_LIBRARY_RELEASE}") + ) + set(OpenSSL_${_comp}_FOUND TRUE) + else() + set(OpenSSL_${_comp}_FOUND FALSE) + endif() + else() + message(WARNING "${_comp} is not a valid OpenSSL component") + set(OpenSSL_${_comp}_FOUND FALSE) + endif() +endforeach() +unset(_comp) + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +find_package_handle_standard_args(OpenSSL + REQUIRED_VARS + OPENSSL_CRYPTO_LIBRARY + OPENSSL_INCLUDE_DIR + VERSION_VAR + OPENSSL_VERSION + HANDLE_COMPONENTS + FAIL_MESSAGE + "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR" +) + +mark_as_advanced(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES) + +if(OPENSSL_FOUND) + if(NOT TARGET OpenSSL::Crypto AND + (EXISTS "${OPENSSL_CRYPTO_LIBRARY}" OR + EXISTS "${LIB_EAY_LIBRARY_DEBUG}" OR + EXISTS "${LIB_EAY_LIBRARY_RELEASE}") + ) + add_library(OpenSSL::Crypto UNKNOWN IMPORTED) + set_target_properties(OpenSSL::Crypto PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${OPENSSL_INCLUDE_DIR}") + if(EXISTS "${OPENSSL_CRYPTO_LIBRARY}") + set_target_properties(OpenSSL::Crypto PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${OPENSSL_CRYPTO_LIBRARY}") + endif() + if(EXISTS "${LIB_EAY_LIBRARY_RELEASE}") + set_property(TARGET OpenSSL::Crypto APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(OpenSSL::Crypto PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" + IMPORTED_LOCATION_RELEASE "${LIB_EAY_LIBRARY_RELEASE}") + endif() + if(EXISTS "${LIB_EAY_LIBRARY_DEBUG}") + set_property(TARGET OpenSSL::Crypto APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(OpenSSL::Crypto PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" + IMPORTED_LOCATION_DEBUG "${LIB_EAY_LIBRARY_DEBUG}") + endif() + endif() + + if(NOT TARGET OpenSSL::SSL AND + (EXISTS "${OPENSSL_SSL_LIBRARY}" OR + EXISTS "${SSL_EAY_LIBRARY_DEBUG}" OR + EXISTS "${SSL_EAY_LIBRARY_RELEASE}") + ) + add_library(OpenSSL::SSL UNKNOWN IMPORTED) + set_target_properties(OpenSSL::SSL PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${OPENSSL_INCLUDE_DIR}") + if(EXISTS "${OPENSSL_SSL_LIBRARY}") + set_target_properties(OpenSSL::SSL PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${OPENSSL_SSL_LIBRARY}") + endif() + if(EXISTS "${SSL_EAY_LIBRARY_RELEASE}") + set_property(TARGET OpenSSL::SSL APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(OpenSSL::SSL PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" + IMPORTED_LOCATION_RELEASE "${SSL_EAY_LIBRARY_RELEASE}") + endif() + if(EXISTS "${SSL_EAY_LIBRARY_DEBUG}") + set_property(TARGET OpenSSL::SSL APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(OpenSSL::SSL PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" + IMPORTED_LOCATION_DEBUG "${SSL_EAY_LIBRARY_DEBUG}") + endif() + if(TARGET OpenSSL::Crypto) + set_target_properties(OpenSSL::SSL PROPERTIES + INTERFACE_LINK_LIBRARIES OpenSSL::Crypto) + endif() + endif() +endif() + +# Restore the original find library ordering +if(OPENSSL_USE_STATIC_LIBS) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${_openssl_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) +endif() diff --git a/Kommon/cmake/FindPackageMessage.cmake b/Kommon/cmake/FindPackageMessage.cmake index 6821cee4f..0628b9816 100644 --- a/Kommon/cmake/FindPackageMessage.cmake +++ b/Kommon/cmake/FindPackageMessage.cmake @@ -1,35 +1,36 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -#.rst: -# FindPackageMessage -# ------------------ -# -# -# -# FIND_PACKAGE_MESSAGE( "message for user" "find result details") -# -# This macro is intended to be used in FindXXX.cmake modules files. It -# will print a message once for each unique find result. This is useful -# for telling the user where a package was found. The first argument -# specifies the name (XXX) of the package. The second argument -# specifies the message to display. The third argument lists details -# about the find result so that if they change the message will be -# displayed again. The macro also obeys the QUIET argument to the -# find_package command. -# -# Example: -# -# :: -# -# if(X11_FOUND) -# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" -# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") -# else() -# ... -# endif() - -function(FIND_PACKAGE_MESSAGE pkg msg details) +#[=======================================================================[.rst: +FindPackageMessage +------------------ + +.. code-block:: cmake + + find_package_message( "message for user" "find result details") + +This function is intended to be used in FindXXX.cmake modules files. +It will print a message once for each unique find result. This is +useful for telling the user where a package was found. The first +argument specifies the name (XXX) of the package. The second argument +specifies the message to display. The third argument lists details +about the find result so that if they change the message will be +displayed again. The macro also obeys the QUIET argument to the +find_package command. + +Example: + +.. code-block:: cmake + + if(X11_FOUND) + find_package_message(X11 "Found X11: ${X11_X11_LIB}" + "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") + else() + ... + endif() +#]=======================================================================] + +function(find_package_message pkg msg details) # Avoid printing a message repeatedly for the same find result. if(NOT ${pkg}_FIND_QUIETLY) string(REPLACE "\n" "" details "${details}") diff --git a/Kommon/cmake/FindPackageMultipass.cmake b/Kommon/cmake/FindPackageMultipass.cmake deleted file mode 100644 index 85dac638d..000000000 --- a/Kommon/cmake/FindPackageMultipass.cmake +++ /dev/null @@ -1,106 +0,0 @@ -# PackageMultipass - this module defines two macros -# -# FIND_PACKAGE_MULTIPASS (Name CURRENT -# STATES VAR0 VAR1 ... -# DEPENDENTS DEP0 DEP1 ...) -# -# This function creates a cache entry _CURRENT which -# the user can set to "NO" to trigger a reconfiguration of the package. -# The first time this function is called, the values of -# _VAR0, ... are saved. If _CURRENT -# is false or if any STATE has changed since the last time -# FIND_PACKAGE_MULTIPASS() was called, then CURRENT will be set to "NO", -# otherwise CURRENT will be "YES". IF not CURRENT, then -# _DEP0, ... will be FORCED to NOTFOUND. -# Example: -# find_path (FOO_DIR include/foo.h) -# FIND_PACKAGE_MULTIPASS (Foo foo_current -# STATES DIR -# DEPENDENTS INCLUDES LIBRARIES) -# if (NOT foo_current) -# # Make temporary files, run programs, etc, to determine FOO_INCLUDES and FOO_LIBRARIES -# endif (NOT foo_current) -# -# MULTIPASS_SOURCE_RUNS (Name INCLUDES LIBRARIES SOURCE RUNS LANGUAGE) -# Always runs the given test, use this when you need to re-run tests -# because parent variables have made old cache entries stale. The LANGUAGE -# variable is either C or CXX indicating which compiler the test should -# use. -# MULTIPASS_C_SOURCE_RUNS (Name INCLUDES LIBRARIES SOURCE RUNS) -# DEPRECATED! This is only included for backwards compatability. Use -# the more general MULTIPASS_SOURCE_RUNS instead. -# Always runs the given test, use this when you need to re-run tests -# because parent variables have made old cache entries stale. - -macro (FIND_PACKAGE_MULTIPASS _name _current) - string (TOUPPER ${_name} _NAME) - set (_args ${ARGV}) - list (REMOVE_AT _args 0 1) - - set (_states_current "YES") - list (GET _args 0 _cmd) - if (_cmd STREQUAL "STATES") - list (REMOVE_AT _args 0) - list (GET _args 0 _state) - while (_state AND NOT _state STREQUAL "DEPENDENTS") - # The name of the stored value for the given state - set (_stored_var PACKAGE_MULTIPASS_${_NAME}_${_state}) - if (NOT "${${_stored_var}}" STREQUAL "${${_NAME}_${_state}}") - set (_states_current "NO") - endif (NOT "${${_stored_var}}" STREQUAL "${${_NAME}_${_state}}") - set (${_stored_var} "${${_NAME}_${_state}}" CACHE INTERNAL "Stored state for ${_name}." FORCE) - list (REMOVE_AT _args 0) - list (GET _args 0 _state) - endwhile (_state AND NOT _state STREQUAL "DEPENDENTS") - endif (_cmd STREQUAL "STATES") - - set (_stored ${_NAME}_CURRENT) - if (NOT ${_stored}) - set (${_stored} "YES" CACHE BOOL "Is the configuration for ${_name} current? Set to \"NO\" to reconfigure." FORCE) - set (_states_current "NO") - endif (NOT ${_stored}) - - set (${_current} ${_states_current}) - if (NOT ${_current} AND PACKAGE_MULTIPASS_${_name}_CALLED) - message (STATUS "Clearing ${_name} dependent variables") - # Clear all the dependent variables so that the module can reset them - list (GET _args 0 _cmd) - if (_cmd STREQUAL "DEPENDENTS") - list (REMOVE_AT _args 0) - foreach (dep ${_args}) - set (${_NAME}_${dep} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) - endforeach (dep) - endif (_cmd STREQUAL "DEPENDENTS") - set (${_NAME}_FOUND "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) - endif () - set (PACKAGE_MULTIPASS_${name}_CALLED YES CACHE INTERNAL "Private" FORCE) -endmacro (FIND_PACKAGE_MULTIPASS) - - -macro (MULTIPASS_SOURCE_RUNS includes libraries source runs language) - include (Check${language}SourceRuns) - # This is a ridiculous hack. CHECK_${language}_SOURCE_* thinks that if the - # *name* of the return variable doesn't change, then the test does - # not need to be re-run. We keep an internal count which we - # increment to guarantee that every test name is unique. If we've - # gotten here, then the configuration has changed enough that the - # test *needs* to be rerun. - if (NOT MULTIPASS_TEST_COUNT) - set (MULTIPASS_TEST_COUNT 00) - endif (NOT MULTIPASS_TEST_COUNT) - math (EXPR _tmp "${MULTIPASS_TEST_COUNT} + 1") # Why can't I add to a cache variable? - set (MULTIPASS_TEST_COUNT ${_tmp} CACHE INTERNAL "Unique test ID") - set (testname MULTIPASS_TEST_${MULTIPASS_TEST_COUNT}_${runs}) - set (CMAKE_REQUIRED_INCLUDES ${includes}) - set (CMAKE_REQUIRED_LIBRARIES ${libraries}) - if(${language} STREQUAL "C") - check_c_source_runs ("${source}" ${testname}) - elseif(${language} STREQUAL "CXX") - check_cxx_source_runs ("${source}" ${testname}) - endif() - set (${runs} "${${testname}}") -endmacro (MULTIPASS_SOURCE_RUNS) - -macro (MULTIPASS_C_SOURCE_RUNS includes libraries source runs) - multipass_source_runs("${includes}" "${libraries}" "${source}" ${runs} "C") -endmacro (MULTIPASS_C_SOURCE_RUNS) \ No newline at end of file diff --git a/Kommon/cmake/FindROOT.cmake b/Kommon/cmake/FindROOT.cmake deleted file mode 100644 index 3b29ba435..000000000 --- a/Kommon/cmake/FindROOT.cmake +++ /dev/null @@ -1,334 +0,0 @@ -############################################################################### -# cmake module for finding ROOTDIRROOT -# -# requires: -# MacroCheckPackageLibs.cmake for checking package libraries -# -# Following cmake variables are returned by this module: -# -# ROOT_FOUND : set to TRUE if ROOT found -# If FIND_PACKAGE is called with REQUIRED and COMPONENTS arguments -# ROOT_FOUND is only set to TRUE if ALL components are found. -# If REQUIRED is NOT set components may or may not be available -# -# ROOT_LIBRARIES : list of ROOT libraries (NOT including COMPONENTS) -# ROOT_INCLUDE_DIRS : list of paths to be used with INCLUDE_DIRECTORIES -# ROOT_LIBRARY_DIRS : list of paths to be used with LINK_DIRECTORIES -# ROOT_COMPONENT_LIBRARIES : list of ROOT component libraries -# ROOT_${COMPONENT}_FOUND : set to TRUE or FALSE for each library -# ROOT_${COMPONENT}_LIBRARY : path to individual libraries -# -# -# Please note that by convention components should be entered exactly as -# the library names, i.e. the component name equivalent to the library -# $ROOTSYS/lib/libMathMore.so should be called MathMore and NOT: -# mathmore or Mathmore or MATHMORE -# -# However to follow the usual cmake convention it is agreed that the -# ROOT_${COMPONENT}_FOUND and ROOT_${COMPONENT}_LIBRARY variables are ALL -# uppercase, i.e. the MathMore component returns: ROOT_MATHMORE_FOUND and -# ROOT_MATHMORE_LIBRARY NOT ROOT_MathMore_FOUND or ROOT_MathMore_LIBRARY -# -# -# The additional ROOT components should be defined as follows: -# FIND_PACKAGE( ROOT COMPONENTS MathMore Gdml Geom ...) -# -# If components are required use: -# FIND_PACKAGE( ROOT REQUIRED COMPONENTS MathMore Gdml Geom ...) -# -# If only root is required and components are NOT required use: -# FIND_PACKAGE( ROOT REQUIRED ) -# FIND_PACKAGE( ROOT COMPONENTS MathMore Gdml Geom ... QUIET ) -# then you need to check for ROOT_MATHMORE_FOUND, ROOT_GDML_FOUND, etc. -# -# The variable ROOT_USE_COMPONENTS can also be used before calling -# FIND_PACKAGE, i.e.: -# SET( ROOT_USE_COMPONENTS MathMore Gdml Geom ) -# FIND_PACKAGE( ROOT REQUIRED ) # all ROOT_USE_COMPONENTS must also be found -# FIND_PACKAGE( ROOT ) # check for ROOT_FOUND, ROOT_MATHMORE_FOUND, etc. -# -# @author Jan Engels, DESY -############################################################################### - -# find root-config -SET( ROOT_CONFIG_EXECUTABLE ROOT_CONFIG_EXECUTABLE-NOTFOUND ) -MARK_AS_ADVANCED( ROOT_CONFIG_EXECUTABLE ) -FIND_PROGRAM( ROOT_CONFIG_EXECUTABLE root-config PATHS $ENV{ROOTSYS}/bin ${ROOT_DIR}/bin NO_DEFAULT_PATH ) -IF( NOT ROOT_DIR ) - FIND_PROGRAM( ROOT_CONFIG_EXECUTABLE root-config ) -ENDIF() - -# find rootcint -SET( ROOT_CINT_EXECUTABLE ROOT_CINT_EXECUTABLE-NOTFOUND ) -MARK_AS_ADVANCED( ROOT_CINT_EXECUTABLE ) -FIND_PROGRAM( ROOT_CINT_EXECUTABLE rootcint PATHS $ENV{ROOTSYS}/bin ${ROOT_DIR}/bin NO_DEFAULT_PATH ) -IF( NOT ROOT_DIR ) - FIND_PROGRAM( ROOT_CINT_EXECUTABLE rootcint ) -ENDIF() - -IF( NOT ROOT_FIND_QUIETLY ) - MESSAGE( STATUS "Check for ROOT_CONFIG_EXECUTABLE: ${ROOT_CONFIG_EXECUTABLE}" ) - MESSAGE( STATUS "Check for ROOT_CINT_EXECUTABLE: ${ROOT_CINT_EXECUTABLE}" ) -ENDIF() - - -IF( ROOT_CONFIG_EXECUTABLE ) - - # ============================================== - # === ROOT_PREFIX === - # ============================================== - - # get root prefix from root-config output - EXECUTE_PROCESS( COMMAND "${ROOT_CONFIG_EXECUTABLE}" --prefix - OUTPUT_VARIABLE ROOT_ROOT - RESULT_VARIABLE _exit_code - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - IF( NOT _exit_code EQUAL 0 ) - # clear variable if root-config exits with error - # it might contain garbage - SET( ROOT_ROOT ) - ELSE() - SET(ROOTSYS ${ROOT_ROOT}) - ENDIF() - - - - # ============================================== - # === ROOT_VERSION === - # ============================================== - - INCLUDE( MacroCheckPackageVersion ) - - EXECUTE_PROCESS( COMMAND "${ROOT_CONFIG_EXECUTABLE}" --version - OUTPUT_VARIABLE _version - RESULT_VARIABLE _exit_code - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - IF( _exit_code EQUAL 0 ) - - # set required variables for MacroCheckPackageVersion - STRING(REGEX REPLACE "^([0-9]+).*" "\\1" ROOT_VERSION_MAJOR "${_version}") - STRING(REGEX REPLACE "^[0-9]+.([0-9]+).*" "\\1" ROOT_VERSION_MINOR "${_version}") - STRING(REGEX REPLACE "^[0-9]+.[0-9]+.([0-9]+).*" "\\1" ROOT_VERSION_PATCH "${_version}") - - SET( ROOT_VERSION "${ROOT_VERSION_MAJOR}.${ROOT_VERSION_MINOR}.${ROOT_VERSION_PATCH}" ) - ENDIF() - - CHECK_PACKAGE_VERSION( ROOT ${ROOT_VERSION} ) - - - - # ============================================== - # === ROOT_INCLUDE_DIR === - # ============================================== - - # get include dir from root-config output - EXECUTE_PROCESS( COMMAND "${ROOT_CONFIG_EXECUTABLE}" --incdir - OUTPUT_VARIABLE _inc_dir - RESULT_VARIABLE _exit_code - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - IF( NOT _exit_code EQUAL 0 ) - # clear _inc_dir if root-config exits with error - # it might contain garbage - SET( _inc_dir ) - ENDIF() - - - SET( ROOT_INCLUDE_DIRS ROOT_INCLUDE_DIRS-NOTFOUND ) - MARK_AS_ADVANCED( ROOT_INCLUDE_DIRS ) - - FIND_PATH( ROOT_INCLUDE_DIRS - NAMES TH1.h - PATHS ${ROOT_DIR}/include ${_inc_dir} - NO_DEFAULT_PATH - ) - - - - # ============================================== - # === ROOT_LIBRARIES === - # ============================================== - - # get library dir from root-config output - EXECUTE_PROCESS( COMMAND "${ROOT_CONFIG_EXECUTABLE}" --libdir - OUTPUT_VARIABLE ROOT_LIBRARY_DIR - RESULT_VARIABLE _exit_code - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - IF( NOT _exit_code EQUAL 0 ) - # clear ROOT_LIBRARY_DIR if root-config exits with error - # it might contain garbage - SET( ROOT_LIBRARY_DIR ) - ENDIF() - - - - # ========== standard root libraries ================= - - # standard root libraries (without components) - SET( _root_libnames ) - - # get standard root libraries from 'root-config --libs' output - EXECUTE_PROCESS( COMMAND "${ROOT_CONFIG_EXECUTABLE}" --noauxlibs --libs - OUTPUT_VARIABLE _aux - RESULT_VARIABLE _exit_code - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - IF( _exit_code EQUAL 0 ) - - # create a list out of the output - SEPARATE_ARGUMENTS( _aux ) - - # remove first item -L compiler flag - LIST( REMOVE_AT _aux 0 ) - - FOREACH( _lib ${_aux} ) - - # extract libnames from -l compiler flags - STRING( REGEX REPLACE "^-.(.*)$" "\\1" _libname "${_lib}") - - # fix for some root-config versions which export -lz even if using --noauxlibs - IF( NOT _libname STREQUAL "z" ) - - # append all library names into a list - LIST( APPEND _root_libnames ${_libname} ) - - ENDIF() - - ENDFOREACH() - - ENDIF() - - - - # ========== additional root components ================= - - #LIST( APPEND ROOT_FIND_COMPONENTS Minuit2 ) # DEPRECATED !!! - - - # ---------- libraries -------------------------------------------------------- - INCLUDE( MacroCheckPackageLibs ) - - SET( ROOT_LIB_SEARCH_PATH ${ROOT_LIBRARY_DIR} ) - - # only standard libraries should be passed as arguments to CHECK_PACKAGE_LIBS - # additional components are set by cmake in variable PKG_FIND_COMPONENTS - # first argument should be the package name - - CHECK_PACKAGE_LIBS( ROOT ${_root_libnames} ) - - # ====== DL LIBRARY ================================================== - # workaround for cmake bug in 64 bit: - # see: http://public.kitware.com/mantis/view.php?id=10813 - IF( CMAKE_SIZEOF_VOID_P EQUAL 8 ) - FIND_LIBRARY( DL_LIB NAMES ${CMAKE_DL_LIBS} dl PATHS /usr/lib64 /lib64 NO_DEFAULT_PATH ) - ENDIF( CMAKE_SIZEOF_VOID_P EQUAL 8 ) - - FIND_LIBRARY( DL_LIB NAMES ${CMAKE_DL_LIBS} dl ) - MARK_AS_ADVANCED( DL_LIB ) - - IF( NOT ROOT_FIND_QUIETLY ) - MESSAGE( STATUS "Check for libdl.so: ${DL_LIB}" ) - ENDIF() - -ENDIF( ROOT_CONFIG_EXECUTABLE ) - -# Threads library -#FIND_PACKAGE( Threads REQUIRED) - - -# ---------- final checking --------------------------------------------------- -INCLUDE( FindPackageHandleStandardArgs ) -# set ROOT_FOUND to TRUE if all listed variables are TRUE and not empty -# ROOT_COMPONENT_VARIABLES will be set if FIND_PACKAGE is called with REQUIRED argument -FIND_PACKAGE_HANDLE_STANDARD_ARGS( ROOT DEFAULT_MSG ROOT_INCLUDE_DIRS ROOT_LIBRARIES ${ROOT_COMPONENT_VARIABLES} PACKAGE_VERSION_COMPATIBLE DL_LIB ) - -IF( ROOT_FOUND ) - LIST( APPEND ROOT_LIBRARIES ${DL_LIB} ) - # FIXME DEPRECATED - SET( ROOT_DEFINITIONS "-DUSEROOT -DUSE_ROOT -DMARLIN_USE_ROOT" ) - MARK_AS_ADVANCED( ROOT_DEFINITIONS ) - - # file including MACROS for generating root dictionary sources - GET_FILENAME_COMPONENT( _aux ${CMAKE_CURRENT_LIST_FILE} PATH ) - SET( ROOT_DICT_MACROS_FILE ${_aux}/MacroRootDict.cmake ) - -ENDIF( ROOT_FOUND ) - -# ---------- cmake bug -------------------------------------------------------- -# ROOT_FIND_REQUIRED is not reset between FIND_PACKAGE calls, i.e. the following -# code fails when geartgeo component not available: (fixed in cmake 2.8) -# FIND_PACKAGE( ROOT REQUIRED ) -# FIND_PACKAGE( ROOT COMPONENTS geartgeo QUIET ) -SET( ROOT_FIND_REQUIRED ) - - -LIST(GET ROOT_INCLUDE_DIRS 0 ROOT_INCLUDE_DIR) -LIST(GET ROOT_LIBRARY_DIRS 0 ROOT_LIBRARY_DIR) - - - -# ---------- dictionary macros---------------------------------------------- - -include(MacroParseArguments) - -#---------------------------------------------------------------------------- -# function ROOT_GENERATE_DICTIONARY( dictionary -# header1 header2 ... -# LINKDEF linkdef1 ... -# OPTIONS opt1...) -function(ROOT_GENERATE_DICTIONARY dictionary) - CMAKE_PARSE_ARGUMENTS(ARG "" "" "LINKDEF;OPTIONS;INCLUDEDIRS" "" ${ARGN}) - #---Get the list of header files------------------------- - set(headerfiles) - foreach(fp ${ARG_UNPARSED_ARGUMENTS}) - file(GLOB files ${fp}) - if(files) - foreach(f ${files}) - if(NOT f MATCHES LinkDef) - set(headerfiles ${headerfiles} ${f}) - endif() - endforeach() - else() - set(headerfiles ${headerfiles} ${fp}) - endif() - endforeach() - #---Get the list of include directories------------------ - #get_directory_property(incdirs INCLUDE_DIRECTORIES) - set(incdirs ${ROOT_INCLUDE_DIRS} ${ARG_INCLUDEDIRS}) - set(includedirs) - foreach( d ${incdirs}) - get_filename_component(d ${d} ABSOLUTE) - set(includedirs ${includedirs} -I${d}) - endforeach() - #---Get LinkDef.h file------------------------------------ - set(linkdefs) - foreach( f ${ARG_LINKDEF}) - if( IS_ABSOLUTE ${f}) - set(linkdefs ${linkdefs} ${f}) - else() - if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/inc/${f}) - set(linkdefs ${linkdefs} ${CMAKE_CURRENT_SOURCE_DIR}/inc/${f}) - else() - set(linkdefs ${linkdefs} ${CMAKE_CURRENT_SOURCE_DIR}/${f}) - endif() - endif() - endforeach() - - #---call rootcint------------------------------------------ - - if (CMAKE_SYSTEM_NAME MATCHES Darwin) - add_custom_command(OUTPUT ${dictionary} - COMMAND DYLD_LIBRARY_PATH=${ROOT_LIBRARY_DIR} ROOTSYS=${ROOTSYS} - ${ROOT_CINT_EXECUTABLE} -cint -f ${dictionary} -c -p -DHAVE_CONFIG_H ${ARG_OPTIONS} ${includedirs} ${headerfiles} ${linkdefs} - DEPENDS ${headerfiles} ${linkdefs} ) - else() - add_custom_command(OUTPUT ${dictionary} - COMMAND LD_LIBRARY_PATH=${ROOT_LIBRARY_DIR}:$ENV{LD_LIBRARY_PATH} ROOTSYS=${ROOTSYS} - ${ROOT_CINT_EXECUTABLE} -cint -f ${dictionary} -c -p -DHAVE_CONFIG_H ${ARG_OPTIONS} ${includedirs} ${headerfiles} ${linkdefs} - DEPENDS ${headerfiles} ${linkdefs} ) - endif() - -endfunction() diff --git a/Kommon/cmake/FindSQLite3.cmake b/Kommon/cmake/FindSQLite3.cmake index 8a471f173..374d7af6c 100644 --- a/Kommon/cmake/FindSQLite3.cmake +++ b/Kommon/cmake/FindSQLite3.cmake @@ -1,37 +1,66 @@ -# Copyright (C) 2007-2009 LuaDist. -# Created by Peter Kapec -# Redistribution and use of this file is allowed according to the terms of the MIT license. -# For details see the COPYRIGHT file distributed with LuaDist. -# Note: -# Searching headers and libraries is very simple and is NOT as powerful as scripts -# distributed with CMake, because LuaDist defines directories to search for. -# Everyone is encouraged to contact the author with improvements. Maybe this file -# becomes part of CMake distribution sometimes. - -# - Find sqlite3 -# Find the native SQLITE3 headers and libraries. -# -# SQLITE3_INCLUDE_DIRS - where to find sqlite3.h, etc. -# SQLITE3_LIBRARIES - List of libraries when using sqlite. -# SQLITE3_FOUND - True if sqlite found. - -# Look for the header file. -FIND_PATH(SQLITE3_INCLUDE_DIR NAMES sqlite3.h) - -# Look for the library. -FIND_LIBRARY(SQLITE3_LIBRARY NAMES sqlite3 libsqlite3) - -# Handle the QUIETLY and REQUIRED arguments and set SQLITE3_FOUND to TRUE if all listed variables are TRUE. -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(SQLITE3 DEFAULT_MSG SQLITE3_LIBRARY SQLITE3_INCLUDE_DIR) - -# Copy the results to the output variables. -IF(SQLITE3_FOUND) - SET(SQLITE3_LIBRARIES ${SQLITE3_LIBRARY}) - SET(SQLITE3_INCLUDE_DIRS ${SQLITE3_INCLUDE_DIR}) -ELSE(SQLITE3_FOUND) - SET(SQLITE3_LIBRARIES) - SET(SQLITE3_INCLUDE_DIRS) -ENDIF(SQLITE3_FOUND) - -MARK_AS_ADVANCED(SQLITE3_INCLUDE_DIRS SQLITE3_LIBRARIES) +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindSQLite3 +----------- + +Find the SQLite libraries, v3 + +IMPORTED targets +^^^^^^^^^^^^^^^^ + +This module defines the following :prop_tgt:`IMPORTED` target: + +``SQLite::SQLite3`` + +Result variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables if found: + +``SQLite3_INCLUDE_DIRS`` + where to find sqlite3.h, etc. +``SQLite3_LIBRARIES`` + the libraries to link against to use SQLite3. +``SQLite3_VERSION`` + version of the SQLite3 library found +``SQLite3_FOUND`` + TRUE if found + +#]=======================================================================] + +# Look for the necessary header +find_path(SQLite3_INCLUDE_DIR NAMES sqlite3.h) +mark_as_advanced(SQLite3_INCLUDE_DIR) + +# Look for the necessary library +find_library(SQLite3_LIBRARY NAMES sqlite3 sqlite) +mark_as_advanced(SQLite3_LIBRARY) + +# Extract version information from the header file +if(SQLite3_INCLUDE_DIR) + file(STRINGS ${SQLite3_INCLUDE_DIR}/sqlite3.h _ver_line + REGEX "^#define SQLITE_VERSION *\"[0-9]+\\.[0-9]+\\.[0-9]+\"" + LIMIT_COUNT 1) + string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" + SQLite3_VERSION "${_ver_line}") + unset(_ver_line) +endif() + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +find_package_handle_standard_args(SQLite3 + REQUIRED_VARS SQLite3_INCLUDE_DIR SQLite3_LIBRARY + VERSION_VAR SQLite3_VERSION) + +# Create the imported target +if(SQLite3_FOUND) + set(SQLite3_INCLUDE_DIRS ${SQLite3_INCLUDE_DIR}) + set(SQLite3_LIBRARIES ${SQLite3_LIBRARY}) + if(NOT TARGET SQLite::SQLite3) + add_library(SQLite::SQLite3 UNKNOWN IMPORTED) + set_target_properties(SQLite::SQLite3 PROPERTIES + IMPORTED_LOCATION "${SQLite3_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${SQLite3_INCLUDE_DIR}") + endif() +endif() diff --git a/Kommon/cmake/FindThreads.cmake b/Kommon/cmake/FindThreads.cmake new file mode 100644 index 000000000..919392ab9 --- /dev/null +++ b/Kommon/cmake/FindThreads.cmake @@ -0,0 +1,205 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindThreads +----------- + +This module determines the thread library of the system. + +The following variables are set + +:: + + CMAKE_THREAD_LIBS_INIT - the thread library + CMAKE_USE_WIN32_THREADS_INIT - using WIN32 threads? + CMAKE_USE_PTHREADS_INIT - are we using pthreads + CMAKE_HP_PTHREADS_INIT - are we using hp pthreads + +The following import target is created + +:: + + Threads::Threads + +If the use of the -pthread compiler and linker flag is preferred then the +caller can set + +:: + + THREADS_PREFER_PTHREAD_FLAG + +The compiler flag can only be used with the imported +target. Use of both the imported target as well as this switch is highly +recommended for new code. + +This module is not needed for C++11 and later if threading is done using +``std::thread`` from the standard library. +#]=======================================================================] + +include (CheckLibraryExists) +include (CheckSymbolExists) +set(Threads_FOUND FALSE) +set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET}) +set(CMAKE_REQUIRED_QUIET ${Threads_FIND_QUIETLY}) + +if(CMAKE_C_COMPILER_LOADED) + include (CheckIncludeFile) +elseif(CMAKE_CXX_COMPILER_LOADED) + include (CheckIncludeFileCXX) +else() + message(FATAL_ERROR "FindThreads only works if either C or CXX language is enabled") +endif() + +# Internal helper macro. +# Do NOT even think about using it outside of this file! +macro(_check_threads_lib LIBNAME FUNCNAME VARNAME) + if(NOT Threads_FOUND) + CHECK_LIBRARY_EXISTS(${LIBNAME} ${FUNCNAME} "" ${VARNAME}) + if(${VARNAME}) + set(CMAKE_THREAD_LIBS_INIT "-l${LIBNAME}") + set(CMAKE_HAVE_THREADS_LIBRARY 1) + set(Threads_FOUND TRUE) + endif() + endif () +endmacro() + +# Internal helper macro. +# Do NOT even think about using it outside of this file! +macro(_check_pthreads_flag) + if(NOT Threads_FOUND) + # If we did not found -lpthread, -lpthread, or -lthread, look for -pthread + if(NOT DEFINED THREADS_HAVE_PTHREAD_ARG) + message(STATUS "Check if compiler accepts -pthread") + if(CMAKE_C_COMPILER_LOADED) + set(_threads_src ${CMAKE_CURRENT_LIST_DIR}/CheckForPthreads.c) + elseif(CMAKE_CXX_COMPILER_LOADED) + set(_threads_src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindThreads/CheckForPthreads.cxx) + configure_file(${CMAKE_CURRENT_LIST_DIR}/CheckForPthreads.c "${_threads_src}" COPYONLY) + endif() + try_compile(THREADS_HAVE_PTHREAD_ARG + ${CMAKE_BINARY_DIR} + ${_threads_src} + CMAKE_FLAGS -DLINK_LIBRARIES:STRING=-pthread + OUTPUT_VARIABLE OUTPUT) + unset(_threads_src) + + if(THREADS_HAVE_PTHREAD_ARG) + set(Threads_FOUND TRUE) + message(STATUS "Check if compiler accepts -pthread - yes") + else() + message(STATUS "Check if compiler accepts -pthread - no") + file(APPEND + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Determining if compiler accepts -pthread failed with the following output:\n${OUTPUT}\n\n") + endif() + + endif() + + if(THREADS_HAVE_PTHREAD_ARG) + set(Threads_FOUND TRUE) + set(CMAKE_THREAD_LIBS_INIT "-pthread") + endif() + endif() +endmacro() + +# Do we have pthreads? +if(CMAKE_C_COMPILER_LOADED) + CHECK_INCLUDE_FILE("pthread.h" CMAKE_HAVE_PTHREAD_H) +else() + CHECK_INCLUDE_FILE_CXX("pthread.h" CMAKE_HAVE_PTHREAD_H) +endif() +if(CMAKE_HAVE_PTHREAD_H) + + # + # We have pthread.h + # Let's check for the library now. + # + set(CMAKE_HAVE_THREADS_LIBRARY) + if(NOT THREADS_HAVE_PTHREAD_ARG) + # Check if pthread functions are in normal C library. + CHECK_SYMBOL_EXISTS(pthread_create pthread.h CMAKE_HAVE_LIBC_CREATE) + if(CMAKE_HAVE_LIBC_CREATE) + set(CMAKE_THREAD_LIBS_INIT "") + set(CMAKE_HAVE_THREADS_LIBRARY 1) + set(Threads_FOUND TRUE) + else() + + # Check for -pthread first if enabled. This is the recommended + # way, but not backwards compatible as one must also pass -pthread + # as compiler flag then. + if (THREADS_PREFER_PTHREAD_FLAG) + _check_pthreads_flag() + endif () + + _check_threads_lib(pthreads pthread_create CMAKE_HAVE_PTHREADS_CREATE) + _check_threads_lib(pthread pthread_create CMAKE_HAVE_PTHREAD_CREATE) + if(CMAKE_SYSTEM_NAME MATCHES "SunOS") + # On sun also check for -lthread + _check_threads_lib(thread thr_create CMAKE_HAVE_THR_CREATE) + endif() + endif() + endif() + + _check_pthreads_flag() +endif() + +if(CMAKE_THREAD_LIBS_INIT OR CMAKE_HAVE_LIBC_CREATE) + set(CMAKE_USE_PTHREADS_INIT 1) + set(Threads_FOUND TRUE) +endif() + +if(CMAKE_SYSTEM_NAME MATCHES "Windows") + set(CMAKE_USE_WIN32_THREADS_INIT 1) + set(Threads_FOUND TRUE) +endif() + +if(CMAKE_USE_PTHREADS_INIT) + if(CMAKE_SYSTEM_NAME MATCHES "HP-UX") + # Use libcma if it exists and can be used. It provides more + # symbols than the plain pthread library. CMA threads + # have actually been deprecated: + # http://docs.hp.com/en/B3920-90091/ch12s03.html#d0e11395 + # http://docs.hp.com/en/947/d8.html + # but we need to maintain compatibility here. + # The CMAKE_HP_PTHREADS setting actually indicates whether CMA threads + # are available. + CHECK_LIBRARY_EXISTS(cma pthread_attr_create "" CMAKE_HAVE_HP_CMA) + if(CMAKE_HAVE_HP_CMA) + set(CMAKE_THREAD_LIBS_INIT "-lcma") + set(CMAKE_HP_PTHREADS_INIT 1) + set(Threads_FOUND TRUE) + endif() + set(CMAKE_USE_PTHREADS_INIT 1) + endif() + + if(CMAKE_SYSTEM MATCHES "OSF1-V") + set(CMAKE_USE_PTHREADS_INIT 0) + set(CMAKE_THREAD_LIBS_INIT ) + endif() + + if(CMAKE_SYSTEM MATCHES "CYGWIN_NT") + set(CMAKE_USE_PTHREADS_INIT 1) + set(Threads_FOUND TRUE) + set(CMAKE_THREAD_LIBS_INIT ) + set(CMAKE_USE_WIN32_THREADS_INIT 0) + endif() +endif() + +set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE}) +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Threads DEFAULT_MSG Threads_FOUND) + +if(THREADS_FOUND AND NOT TARGET Threads::Threads) + add_library(Threads::Threads INTERFACE IMPORTED) + + if(THREADS_HAVE_PTHREAD_ARG) + set_property(TARGET Threads::Threads + PROPERTY INTERFACE_COMPILE_OPTIONS "$<$:SHELL:-Xcompiler -pthread>" + "$<$>:-pthread>") + endif() + + if(CMAKE_THREAD_LIBS_INIT) + set_property(TARGET Threads::Threads PROPERTY INTERFACE_LINK_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}") + endif() +endif() diff --git a/Kommon/cmake/FindZLIB.cmake b/Kommon/cmake/FindZLIB.cmake new file mode 100644 index 000000000..790eb423c --- /dev/null +++ b/Kommon/cmake/FindZLIB.cmake @@ -0,0 +1,149 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindZLIB +-------- + +Find the native ZLIB includes and library. + +IMPORTED Targets +^^^^^^^^^^^^^^^^ + +This module defines :prop_tgt:`IMPORTED` target ``ZLIB::ZLIB``, if +ZLIB has been found. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module defines the following variables: + +:: + + ZLIB_INCLUDE_DIRS - where to find zlib.h, etc. + ZLIB_LIBRARIES - List of libraries when using zlib. + ZLIB_FOUND - True if zlib found. + +:: + + ZLIB_VERSION_STRING - The version of zlib found (x.y.z) + ZLIB_VERSION_MAJOR - The major version of zlib + ZLIB_VERSION_MINOR - The minor version of zlib + ZLIB_VERSION_PATCH - The patch version of zlib + ZLIB_VERSION_TWEAK - The tweak version of zlib + +Backward Compatibility +^^^^^^^^^^^^^^^^^^^^^^ + +The following variable are provided for backward compatibility + +:: + + ZLIB_MAJOR_VERSION - The major version of zlib + ZLIB_MINOR_VERSION - The minor version of zlib + ZLIB_PATCH_VERSION - The patch version of zlib + +Hints +^^^^^ + +A user may set ``ZLIB_ROOT`` to a zlib installation root to tell this +module where to look. +#]=======================================================================] + +set(_ZLIB_SEARCHES) + +# Search ZLIB_ROOT first if it is set. +if(ZLIB_ROOT) + set(_ZLIB_SEARCH_ROOT PATHS ${ZLIB_ROOT} NO_DEFAULT_PATH) + list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_ROOT) +endif() + +# Normal search. +set(_ZLIB_x86 "(x86)") +set(_ZLIB_SEARCH_NORMAL + PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Zlib;InstallPath]" + "$ENV{ProgramFiles}/zlib" + "$ENV{ProgramFiles${_ZLIB_x86}}/zlib") +unset(_ZLIB_x86) +list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_NORMAL) + +set(ZLIB_NAMES z zlib zdll zlib1) +set(ZLIB_NAMES_DEBUG zlibd zlibd1) + +# Try each search configuration. +foreach(search ${_ZLIB_SEARCHES}) + find_path(ZLIB_INCLUDE_DIR NAMES zlib.h ${${search}} PATH_SUFFIXES include) +endforeach() + +# Allow ZLIB_LIBRARY to be set manually, as the location of the zlib library +if(NOT ZLIB_LIBRARY) + foreach(search ${_ZLIB_SEARCHES}) + find_library(ZLIB_LIBRARY_RELEASE NAMES ${ZLIB_NAMES} NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib) + find_library(ZLIB_LIBRARY_DEBUG NAMES ${ZLIB_NAMES_DEBUG} NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib) + endforeach() + + include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) + select_library_configurations(ZLIB) +endif() + +unset(ZLIB_NAMES) +unset(ZLIB_NAMES_DEBUG) + +mark_as_advanced(ZLIB_INCLUDE_DIR) + +if(ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h") + file(STRINGS "${ZLIB_INCLUDE_DIR}/zlib.h" ZLIB_H REGEX "^#define ZLIB_VERSION \"[^\"]*\"$") + + string(REGEX REPLACE "^.*ZLIB_VERSION \"([0-9]+).*$" "\\1" ZLIB_VERSION_MAJOR "${ZLIB_H}") + string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_MINOR "${ZLIB_H}") + string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_PATCH "${ZLIB_H}") + set(ZLIB_VERSION_STRING "${ZLIB_VERSION_MAJOR}.${ZLIB_VERSION_MINOR}.${ZLIB_VERSION_PATCH}") + + # only append a TWEAK version if it exists: + set(ZLIB_VERSION_TWEAK "") + if( "${ZLIB_H}" MATCHES "ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+)") + set(ZLIB_VERSION_TWEAK "${CMAKE_MATCH_1}") + string(APPEND ZLIB_VERSION_STRING ".${ZLIB_VERSION_TWEAK}") + endif() + + set(ZLIB_MAJOR_VERSION "${ZLIB_VERSION_MAJOR}") + set(ZLIB_MINOR_VERSION "${ZLIB_VERSION_MINOR}") + set(ZLIB_PATCH_VERSION "${ZLIB_VERSION_PATCH}") +endif() + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZLIB REQUIRED_VARS ZLIB_LIBRARY ZLIB_INCLUDE_DIR + VERSION_VAR ZLIB_VERSION_STRING) + +if(ZLIB_FOUND) + set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR}) + + if(NOT ZLIB_LIBRARIES) + set(ZLIB_LIBRARIES ${ZLIB_LIBRARY}) + endif() + + if(NOT TARGET ZLIB::ZLIB) + add_library(ZLIB::ZLIB UNKNOWN IMPORTED) + set_target_properties(ZLIB::ZLIB PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INCLUDE_DIRS}") + + if(ZLIB_LIBRARY_RELEASE) + set_property(TARGET ZLIB::ZLIB APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(ZLIB::ZLIB PROPERTIES + IMPORTED_LOCATION_RELEASE "${ZLIB_LIBRARY_RELEASE}") + endif() + + if(ZLIB_LIBRARY_DEBUG) + set_property(TARGET ZLIB::ZLIB APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(ZLIB::ZLIB PROPERTIES + IMPORTED_LOCATION_DEBUG "${ZLIB_LIBRARY_DEBUG}") + endif() + + if(NOT ZLIB_LIBRARY_RELEASE AND NOT ZLIB_LIBRARY_DEBUG) + set_property(TARGET ZLIB::ZLIB APPEND PROPERTY + IMPORTED_LOCATION "${ZLIB_LIBRARY}") + endif() + endif() +endif() diff --git a/Kommon/cmake/GNUInstallDirs.cmake b/Kommon/cmake/GNUInstallDirs.cmake new file mode 100644 index 000000000..4db4e18fd --- /dev/null +++ b/Kommon/cmake/GNUInstallDirs.cmake @@ -0,0 +1,383 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +GNUInstallDirs +-------------- + +Define GNU standard installation directories + +Provides install directory variables as defined by the +`GNU Coding Standards`_. + +.. _`GNU Coding Standards`: https://www.gnu.org/prep/standards/html_node/Directory-Variables.html + +Result Variables +^^^^^^^^^^^^^^^^ + +Inclusion of this module defines the following variables: + +``CMAKE_INSTALL_`` + + Destination for files of a given type. This value may be passed to + the ``DESTINATION`` options of :command:`install` commands for the + corresponding file type. + +``CMAKE_INSTALL_FULL_`` + + The absolute path generated from the corresponding ``CMAKE_INSTALL_`` + value. If the value is not already an absolute path, an absolute path + is constructed typically by prepending the value of the + :variable:`CMAKE_INSTALL_PREFIX` variable. However, there are some + `special cases`_ as documented below. + +where ```` is one of: + +``BINDIR`` + user executables (``bin``) +``SBINDIR`` + system admin executables (``sbin``) +``LIBEXECDIR`` + program executables (``libexec``) +``SYSCONFDIR`` + read-only single-machine data (``etc``) +``SHAREDSTATEDIR`` + modifiable architecture-independent data (``com``) +``LOCALSTATEDIR`` + modifiable single-machine data (``var``) +``RUNSTATEDIR`` + run-time variable data (``LOCALSTATEDIR/run``) +``LIBDIR`` + object code libraries (``lib`` or ``lib64`` + or ``lib/`` on Debian) +``INCLUDEDIR`` + C header files (``include``) +``OLDINCLUDEDIR`` + C header files for non-gcc (``/usr/include``) +``DATAROOTDIR`` + read-only architecture-independent data root (``share``) +``DATADIR`` + read-only architecture-independent data (``DATAROOTDIR``) +``INFODIR`` + info documentation (``DATAROOTDIR/info``) +``LOCALEDIR`` + locale-dependent data (``DATAROOTDIR/locale``) +``MANDIR`` + man documentation (``DATAROOTDIR/man``) +``DOCDIR`` + documentation root (``DATAROOTDIR/doc/PROJECT_NAME``) + +If the includer does not define a value the above-shown default will be +used and the value will appear in the cache for editing by the user. + +Special Cases +^^^^^^^^^^^^^ + +The following values of :variable:`CMAKE_INSTALL_PREFIX` are special: + +``/`` + + For ```` other than the ``SYSCONFDIR``, ``LOCALSTATEDIR`` and + ``RUNSTATEDIR``, the value of ``CMAKE_INSTALL_`` is prefixed + with ``usr/`` if it is not user-specified as an absolute path. + For example, the ``INCLUDEDIR`` value ``include`` becomes ``usr/include``. + This is required by the `GNU Coding Standards`_, which state: + + When building the complete GNU system, the prefix will be empty + and ``/usr`` will be a symbolic link to ``/``. + +``/usr`` + + For ```` equal to ``SYSCONFDIR``, ``LOCALSTATEDIR`` or + ``RUNSTATEDIR``, the ``CMAKE_INSTALL_FULL_`` is computed by + prepending just ``/`` to the value of ``CMAKE_INSTALL_`` + if it is not user-specified as an absolute path. + For example, the ``SYSCONFDIR`` value ``etc`` becomes ``/etc``. + This is required by the `GNU Coding Standards`_. + +``/opt/...`` + + For ```` equal to ``SYSCONFDIR``, ``LOCALSTATEDIR`` or + ``RUNSTATEDIR``, the ``CMAKE_INSTALL_FULL_`` is computed by + *appending* the prefix to the value of ``CMAKE_INSTALL_`` + if it is not user-specified as an absolute path. + For example, the ``SYSCONFDIR`` value ``etc`` becomes ``/etc/opt/...``. + This is defined by the `Filesystem Hierarchy Standard`_. + +.. _`Filesystem Hierarchy Standard`: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html + +Macros +^^^^^^ + +.. command:: GNUInstallDirs_get_absolute_install_dir + + :: + + GNUInstallDirs_get_absolute_install_dir(absvar var) + + Set the given variable ``absvar`` to the absolute path contained + within the variable ``var``. This is to allow the computation of an + absolute path, accounting for all the special cases documented + above. While this macro is used to compute the various + ``CMAKE_INSTALL_FULL_`` variables, it is exposed publicly to + allow users who create additional path variables to also compute + absolute paths where necessary, using the same logic. +#]=======================================================================] + +cmake_policy(PUSH) +cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced + +# Convert a cache variable to PATH type + +macro(_GNUInstallDirs_cache_convert_to_path var description) + get_property(_GNUInstallDirs_cache_type CACHE ${var} PROPERTY TYPE) + if(_GNUInstallDirs_cache_type STREQUAL "UNINITIALIZED") + file(TO_CMAKE_PATH "${${var}}" _GNUInstallDirs_cmakepath) + set_property(CACHE ${var} PROPERTY TYPE PATH) + set_property(CACHE ${var} PROPERTY VALUE "${_GNUInstallDirs_cmakepath}") + set_property(CACHE ${var} PROPERTY HELPSTRING "${description}") + unset(_GNUInstallDirs_cmakepath) + endif() + unset(_GNUInstallDirs_cache_type) +endmacro() + +# Create a cache variable with default for a path. +macro(_GNUInstallDirs_cache_path var default description) + if(NOT DEFINED ${var}) + set(${var} "${default}" CACHE PATH "${description}") + endif() + _GNUInstallDirs_cache_convert_to_path("${var}" "${description}") +endmacro() + +# Create a cache variable with not default for a path, with a fallback +# when unset; used for entries slaved to other entries such as +# DATAROOTDIR. +macro(_GNUInstallDirs_cache_path_fallback var default description) + if(NOT ${var}) + set(${var} "" CACHE PATH "${description}") + set(${var} "${default}") + endif() + _GNUInstallDirs_cache_convert_to_path("${var}" "${description}") +endmacro() + +# Installation directories +# + +_GNUInstallDirs_cache_path(CMAKE_INSTALL_BINDIR "bin" + "User executables (bin)") +_GNUInstallDirs_cache_path(CMAKE_INSTALL_SBINDIR "sbin" + "System admin executables (sbin)") +_GNUInstallDirs_cache_path(CMAKE_INSTALL_LIBEXECDIR "libexec" + "Program executables (libexec)") +_GNUInstallDirs_cache_path(CMAKE_INSTALL_SYSCONFDIR "etc" + "Read-only single-machine data (etc)") +_GNUInstallDirs_cache_path(CMAKE_INSTALL_SHAREDSTATEDIR "com" + "Modifiable architecture-independent data (com)") +_GNUInstallDirs_cache_path(CMAKE_INSTALL_LOCALSTATEDIR "var" + "Modifiable single-machine data (var)") + +# We check if the variable was manually set and not cached, in order to +# allow projects to set the values as normal variables before including +# GNUInstallDirs to avoid having the entries cached or user-editable. It +# replaces the "if(NOT DEFINED CMAKE_INSTALL_XXX)" checks in all the +# other cases. +# If CMAKE_INSTALL_LIBDIR is defined, if _libdir_set is false, then the +# variable is a normal one, otherwise it is a cache one. +get_property(_libdir_set CACHE CMAKE_INSTALL_LIBDIR PROPERTY TYPE SET) +if(NOT DEFINED CMAKE_INSTALL_LIBDIR OR (_libdir_set + AND DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX + AND NOT "${_GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX}" STREQUAL "${CMAKE_INSTALL_PREFIX}")) + # If CMAKE_INSTALL_LIBDIR is not defined, it is always executed. + # Otherwise: + # * if _libdir_set is false it is not executed (meaning that it is + # not a cache variable) + # * if _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX is not defined it is + # not executed + # * if _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX and + # CMAKE_INSTALL_PREFIX are the same string it is not executed. + # _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX is updated after the + # execution, of this part of code, therefore at the next inclusion + # of the file, CMAKE_INSTALL_LIBDIR is defined, and the 2 strings + # are equal, meaning that the if is not executed the code the + # second time. + + set(_LIBDIR_DEFAULT "lib") + # Override this default 'lib' with 'lib64' iff: + # - we are on Linux system but NOT cross-compiling + # - we are NOT on debian + # - we are on a 64 bits system + # reason is: amd64 ABI: https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI + # For Debian with multiarch, use 'lib/${CMAKE_LIBRARY_ARCHITECTURE}' if + # CMAKE_LIBRARY_ARCHITECTURE is set (which contains e.g. "i386-linux-gnu" + # and CMAKE_INSTALL_PREFIX is "/usr" + # See http://wiki.debian.org/Multiarch + if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX) + set(__LAST_LIBDIR_DEFAULT "lib") + # __LAST_LIBDIR_DEFAULT is the default value that we compute from + # _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX, not a cache entry for + # the value that was last used as the default. + # This value is used to figure out whether the user changed the + # CMAKE_INSTALL_LIBDIR value manually, or if the value was the + # default one. When CMAKE_INSTALL_PREFIX changes, the value is + # updated to the new default, unless the user explicitly changed it. + endif() + if(CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$" + AND NOT CMAKE_CROSSCOMPILING) + if (EXISTS "/etc/debian_version") # is this a debian system ? + if(CMAKE_LIBRARY_ARCHITECTURE) + if("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$") + set(_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}") + endif() + if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX + AND "${_GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$") + set(__LAST_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}") + endif() + endif() + else() # not debian, rely on CMAKE_SIZEOF_VOID_P: + if(NOT DEFINED CMAKE_SIZEOF_VOID_P) + message(AUTHOR_WARNING + "Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. " + "Please enable at least one language before including GNUInstallDirs.") + else() + if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") + set(_LIBDIR_DEFAULT "lib64") + if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX) + set(__LAST_LIBDIR_DEFAULT "lib64") + endif() + endif() + endif() + endif() + endif() + if(NOT DEFINED CMAKE_INSTALL_LIBDIR) + set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "Object code libraries (${_LIBDIR_DEFAULT})") + elseif(DEFINED __LAST_LIBDIR_DEFAULT + AND "${__LAST_LIBDIR_DEFAULT}" STREQUAL "${CMAKE_INSTALL_LIBDIR}") + set_property(CACHE CMAKE_INSTALL_LIBDIR PROPERTY VALUE "${_LIBDIR_DEFAULT}") + endif() +endif() +_GNUInstallDirs_cache_convert_to_path(CMAKE_INSTALL_LIBDIR "Object code libraries (lib)") + +# Save for next run +set(_GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" CACHE INTERNAL "CMAKE_INSTALL_PREFIX during last run") +unset(_libdir_set) +unset(__LAST_LIBDIR_DEFAULT) + +_GNUInstallDirs_cache_path(CMAKE_INSTALL_INCLUDEDIR "include" + "C header files (include)") +_GNUInstallDirs_cache_path(CMAKE_INSTALL_OLDINCLUDEDIR "/usr/include" + "C header files for non-gcc (/usr/include)") +_GNUInstallDirs_cache_path(CMAKE_INSTALL_DATAROOTDIR "share" + "Read-only architecture-independent data root (share)") + +#----------------------------------------------------------------------------- +# Values whose defaults are relative to DATAROOTDIR. Store empty values in +# the cache and store the defaults in local variables if the cache values are +# not set explicitly. This auto-updates the defaults as DATAROOTDIR changes. + +_GNUInstallDirs_cache_path_fallback(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}" + "Read-only architecture-independent data (DATAROOTDIR)") + +if(CMAKE_SYSTEM_NAME MATCHES "^(([^kF].*)?BSD|DragonFly)$") + _GNUInstallDirs_cache_path_fallback(CMAKE_INSTALL_INFODIR "info" + "Info documentation (info)") +else() + _GNUInstallDirs_cache_path_fallback(CMAKE_INSTALL_INFODIR "${CMAKE_INSTALL_DATAROOTDIR}/info" + "Info documentation (DATAROOTDIR/info)") +endif() + +if(CMAKE_SYSTEM_NAME MATCHES "^(([^k].*)?BSD|DragonFly)$") + _GNUInstallDirs_cache_path_fallback(CMAKE_INSTALL_MANDIR "man" + "Man documentation (man)") +else() + _GNUInstallDirs_cache_path_fallback(CMAKE_INSTALL_MANDIR "${CMAKE_INSTALL_DATAROOTDIR}/man" + "Man documentation (DATAROOTDIR/man)") +endif() + +_GNUInstallDirs_cache_path_fallback(CMAKE_INSTALL_LOCALEDIR "${CMAKE_INSTALL_DATAROOTDIR}/locale" + "Locale-dependent data (DATAROOTDIR/locale)") +_GNUInstallDirs_cache_path_fallback(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}" + "Documentation root (DATAROOTDIR/doc/PROJECT_NAME)") + +_GNUInstallDirs_cache_path_fallback(CMAKE_INSTALL_RUNSTATEDIR "${CMAKE_INSTALL_LOCALSTATEDIR}/run" + "Run-time variable data (LOCALSTATEDIR/run)") + +#----------------------------------------------------------------------------- + +mark_as_advanced( + CMAKE_INSTALL_BINDIR + CMAKE_INSTALL_SBINDIR + CMAKE_INSTALL_LIBEXECDIR + CMAKE_INSTALL_SYSCONFDIR + CMAKE_INSTALL_SHAREDSTATEDIR + CMAKE_INSTALL_LOCALSTATEDIR + CMAKE_INSTALL_RUNSTATEDIR + CMAKE_INSTALL_LIBDIR + CMAKE_INSTALL_INCLUDEDIR + CMAKE_INSTALL_OLDINCLUDEDIR + CMAKE_INSTALL_DATAROOTDIR + CMAKE_INSTALL_DATADIR + CMAKE_INSTALL_INFODIR + CMAKE_INSTALL_LOCALEDIR + CMAKE_INSTALL_MANDIR + CMAKE_INSTALL_DOCDIR + ) + +macro(GNUInstallDirs_get_absolute_install_dir absvar var) + if(NOT IS_ABSOLUTE "${${var}}") + # Handle special cases: + # - CMAKE_INSTALL_PREFIX == / + # - CMAKE_INSTALL_PREFIX == /usr + # - CMAKE_INSTALL_PREFIX == /opt/... + if("${CMAKE_INSTALL_PREFIX}" STREQUAL "/") + if("${dir}" STREQUAL "SYSCONFDIR" OR "${dir}" STREQUAL "LOCALSTATEDIR" OR "${dir}" STREQUAL "RUNSTATEDIR") + set(${absvar} "/${${var}}") + else() + if (NOT "${${var}}" MATCHES "^usr/") + set(${var} "usr/${${var}}") + endif() + set(${absvar} "/${${var}}") + endif() + elseif("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$") + if("${dir}" STREQUAL "SYSCONFDIR" OR "${dir}" STREQUAL "LOCALSTATEDIR" OR "${dir}" STREQUAL "RUNSTATEDIR") + set(${absvar} "/${${var}}") + else() + set(${absvar} "${CMAKE_INSTALL_PREFIX}/${${var}}") + endif() + elseif("${CMAKE_INSTALL_PREFIX}" MATCHES "^/opt/.*") + if("${dir}" STREQUAL "SYSCONFDIR" OR "${dir}" STREQUAL "LOCALSTATEDIR" OR "${dir}" STREQUAL "RUNSTATEDIR") + set(${absvar} "/${${var}}${CMAKE_INSTALL_PREFIX}") + else() + set(${absvar} "${CMAKE_INSTALL_PREFIX}/${${var}}") + endif() + else() + set(${absvar} "${CMAKE_INSTALL_PREFIX}/${${var}}") + endif() + else() + set(${absvar} "${${var}}") + endif() +endmacro() + +# Result directories +# +foreach(dir + BINDIR + SBINDIR + LIBEXECDIR + SYSCONFDIR + SHAREDSTATEDIR + LOCALSTATEDIR + RUNSTATEDIR + LIBDIR + INCLUDEDIR + OLDINCLUDEDIR + DATAROOTDIR + DATADIR + INFODIR + LOCALEDIR + MANDIR + DOCDIR + ) + GNUInstallDirs_get_absolute_install_dir(CMAKE_INSTALL_FULL_${dir} CMAKE_INSTALL_${dir}) +endforeach() + +cmake_policy(POP) diff --git a/Kommon/cmake/KasperDefaults.cmake b/Kommon/cmake/KasperDefaults.cmake index 956978834..a8427ea33 100644 --- a/Kommon/cmake/KasperDefaults.cmake +++ b/Kommon/cmake/KasperDefaults.cmake @@ -1,3 +1,5 @@ +cmake_policy(SET CMP0048 NEW) + macro(set_path var value comment) if(NOT DEFINED ${var}) set(${var} "${value}") @@ -14,6 +16,13 @@ if( ${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR} ) set(STANDALONE true) + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeCache.txt") + message(FATAL_ERROR "Please remove the file '${CMAKE_CURRENT_SOURCE_DIR}/CMakeCache.txt' before running `cmake`.") + endif() + if("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}" OR EXISTS "${CMAKE_CURRENT_BINARY_DIR}/CMakeLists.txt") + message(FATAL_ERROR "Please run the `cmake` command from the build directory, not inside the source tree! See the file 'README.md' for instructions.") + endif() + # use this section to modifiy initial values of builtin CMAKE variables if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) @@ -89,9 +98,7 @@ if( ${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR} ) else() set(STANDALONE false) - # cleanup include dir definitions for this module - set(MODULE_HEADER_DIRS) - set(EXTERNAL_INCLUDE_DIRS) + set_property(GLOBAL PROPERTY ${PROJECT_NAME}_LIBRARIES "") endif() macro(kasper_set_version_numbers VERSION_VAR) @@ -110,26 +117,30 @@ macro(kasper_set_version_numbers VERSION_VAR) endif() math( EXPR ${VERSION_VAR}_NUMERICAL "(${${VERSION_VAR}_MAJOR} * 10000) + (${${VERSION_VAR}_MINOR} * 100) + ${${VERSION_VAR}_PATCH}" ) + if(NOT PROJECT_VERSION) + set( PROJECT_VERSION_MAJOR ${${VERSION_VAR}_MAJOR} ) + set( PROJECT_VERSION_MINOR ${${VERSION_VAR}_MINOR} ) + set( PROJECT_VERSION_PATCH ${${VERSION_VAR}_PATCH} ) + set( PROJECT_VERSION ${${VERSION_VAR}} ) + endif() + set( ${PROJECT_NAME}_VERSION_MAJOR ${${VERSION_VAR}_MAJOR} ) set( ${PROJECT_NAME}_VERSION_MINOR ${${VERSION_VAR}_MINOR} ) set( ${PROJECT_NAME}_VERSION_PATCH ${${VERSION_VAR}_PATCH} ) set( ${PROJECT_NAME}_VERSION_NUMERICAL ${${VERSION_VAR}_NUMERICAL} ) set( ${PROJECT_NAME}_VERSION ${${VERSION_VAR}} ) - add_definitions( -D${PROJECT_NAME}_VERSION_MAJOR=${${PROJECT_NAME}_VERSION_MAJOR} ) - add_definitions( -D${PROJECT_NAME}_VERSION_MINOR=${${PROJECT_NAME}_VERSION_MINOR} ) - add_definitions( -D${PROJECT_NAME}_VERSION_PATCH=${${PROJECT_NAME}_VERSION_PATCH} ) - add_definitions( -D${PROJECT_NAME}_VERSION_NUMERICAL=${${PROJECT_NAME}_VERSION_NUMERICAL} ) - add_definitions( -D${PROJECT_NAME}_VERSION="${${PROJECT_NAME}_VERSION}" ) + add_compile_definitions( ${PROJECT_NAME}_VERSION_MAJOR=${${PROJECT_NAME}_VERSION_MAJOR} ) + add_compile_definitions( ${PROJECT_NAME}_VERSION_MINOR=${${PROJECT_NAME}_VERSION_MINOR} ) + add_compile_definitions( ${PROJECT_NAME}_VERSION_PATCH=${${PROJECT_NAME}_VERSION_PATCH} ) + add_compile_definitions( ${PROJECT_NAME}_VERSION_NUMERICAL=${${PROJECT_NAME}_VERSION_NUMERICAL} ) + add_compile_definitions( ${PROJECT_NAME}_VERSION="${${PROJECT_NAME}_VERSION}" ) endmacro() if( ${PROJECT_NAME} STREQUAL Kasper ) kasper_set_version_numbers(KASPER_VERSION) message(STATUS "Kasper version is v${KASPER_VERSION} (${KASPER_VERSION_NUMERICAL})" ) - set_property(GLOBAL PROPERTY MODULE_TARGETS) - set_property(GLOBAL PROPERTY MODULE_DIRS) - # git revision (if available) set(KASPER_GIT_REVISION "n/a") if(EXISTS "${CMAKE_SOURCE_DIR}/.git/index") @@ -167,7 +178,6 @@ if( ${PROJECT_NAME} STREQUAL Kasper ) else() kasper_set_version_numbers(MODULE_VERSION) - set_property(GLOBAL APPEND PROPERTY MODULE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}) message(STATUS "Kasper module enabled: ${PROJECT_NAME} v${${PROJECT_NAME}_VERSION} (${${PROJECT_NAME}_VERSION_NUMERICAL})" ) endif() @@ -192,29 +202,28 @@ macro( kasper_module_paths PATH ) set( ${PROJECT_NAME}_LOG_INSTALL_DIR "${LOG_INSTALL_DIR}/${PATH}" ) set( ${PROJECT_NAME}_CACHE_INSTALL_DIR "${CACHE_INSTALL_DIR}/${PATH}" ) - add_definitions( -DKASPER_INSTALL_DIR=${KASPER_INSTALL_DIR} ) + add_compile_definitions( KASPER_INSTALL_DIR=${KASPER_INSTALL_DIR} ) - add_definitions( -DINCLUDE_INSTALL_DIR=${${PROJECT_NAME}_INCLUDE_INSTALL_DIR} ) + add_compile_definitions( INCLUDE_INSTALL_DIR=${${PROJECT_NAME}_INCLUDE_INSTALL_DIR} ) install(CODE "file(MAKE_DIRECTORY \"${${PROJECT_NAME}_INCLUDE_INSTALL_DIR}\")" ) - add_definitions( -DLIB_INSTALL_DIR=${${PROJECT_NAME}_LIB_INSTALL_DIR} ) + add_compile_definitions( LIB_INSTALL_DIR=${${PROJECT_NAME}_LIB_INSTALL_DIR} ) install(CODE "file(MAKE_DIRECTORY \"${${PROJECT_NAME}_LIB_INSTALL_DIR}\")" ) - add_definitions( -DBIN_INSTALL_DIR=${${PROJECT_NAME}_BIN_INSTALL_DIR} ) + add_compile_definitions( BIN_INSTALL_DIR=${${PROJECT_NAME}_BIN_INSTALL_DIR} ) install(CODE "file(MAKE_DIRECTORY \"${${PROJECT_NAME}_BIN_INSTALL_DIR}\")" ) - #add_definitions( -DDOC_INSTALL_DIR=${${PROJECT_NAME}_DOC_INSTALL_DIR} ) + #add_compile_definitions( DOC_INSTALL_DIR=${${PROJECT_NAME}_DOC_INSTALL_DIR} ) #install(CODE "file(MAKE_DIRECTORY \"${${PROJECT_NAME}_DOC_INSTALL_DIR}\")" ) - add_definitions( -DCONFIG_INSTALL_DIR=${${PROJECT_NAME}_CONFIG_INSTALL_DIR} ) + add_compile_definitions( CONFIG_INSTALL_DIR=${${PROJECT_NAME}_CONFIG_INSTALL_DIR} ) install(CODE "file(MAKE_DIRECTORY \"${${PROJECT_NAME}_CONFIG_INSTALL_DIR}\")" ) - add_definitions( -DDATA_INSTALL_DIR=${${PROJECT_NAME}_DATA_INSTALL_DIR} ) + add_compile_definitions( DATA_INSTALL_DIR=${${PROJECT_NAME}_DATA_INSTALL_DIR} ) install(CODE "file(MAKE_DIRECTORY \"${${PROJECT_NAME}_DATA_INSTALL_DIR}\")" ) - add_definitions( -DSCRATCH_INSTALL_DIR=${${PROJECT_NAME}_SCRATCH_INSTALL_DIR} ) + add_compile_definitions( SCRATCH_INSTALL_DIR=${${PROJECT_NAME}_SCRATCH_INSTALL_DIR} ) install(CODE "file(MAKE_DIRECTORY \"${${PROJECT_NAME}_SCRATCH_INSTALL_DIR}\")" ) - add_definitions( -DOUTPUT_INSTALL_DIR=${${PROJECT_NAME}_OUTPUT_INSTALL_DIR} ) + add_compile_definitions( OUTPUT_INSTALL_DIR=${${PROJECT_NAME}_OUTPUT_INSTALL_DIR} ) install(CODE "file(MAKE_DIRECTORY \"${${PROJECT_NAME}_OUTPUT_INSTALL_DIR}\")" ) - add_definitions( -DLOG_INSTALL_DIR=${${PROJECT_NAME}_LOG_INSTALL_DIR} ) + add_compile_definitions( LOG_INSTALL_DIR=${${PROJECT_NAME}_LOG_INSTALL_DIR} ) install(CODE "file(MAKE_DIRECTORY \"${${PROJECT_NAME}_LOG_INSTALL_DIR}\")" ) - add_definitions( -DCACHE_INSTALL_DIR=${${PROJECT_NAME}_CACHE_INSTALL_DIR} ) + add_compile_definitions( CACHE_INSTALL_DIR=${${PROJECT_NAME}_CACHE_INSTALL_DIR} ) install(CODE "file(MAKE_DIRECTORY \"${${PROJECT_NAME}_CACHE_INSTALL_DIR}\")" ) - endmacro() #################### @@ -227,13 +236,13 @@ macro( kasper_module_debug ) if (${ARGC} GREATER 0) set( ${PROJECT_NAME}_ENABLE_${ARGV0}_DEBUG OFF CACHE BOOL ${ARGV1} ) if( ${PROJECT_NAME}_ENABLE_${ARGV0}_DEBUG ) - add_definitions( -D${PROJECT_NAME}_ENABLE_${ARGV0}_DEBUG ) + add_compile_definitions( ${PROJECT_NAME}_ENABLE_${ARGV0}_DEBUG ) endif() # global module debug option else() set( ${PROJECT_NAME}_ENABLE_DEBUG OFF CACHE BOOL "build debug output for ${PROJECT_NAME}" ) if( ${PROJECT_NAME}_ENABLE_DEBUG ) - add_definitions( -D${PROJECT_NAME}_ENABLE_DEBUG ) + add_compile_definitions( ${PROJECT_NAME}_ENABLE_DEBUG ) endif() endif() endmacro() @@ -246,7 +255,7 @@ endmacro() macro( kasper_module_test TEST ) set( ${PROJECT_NAME}_ENABLE_TEST OFF CACHE BOOL "build test programs for ${PROJECT_NAME}" ) if( ${PROJECT_NAME}_ENABLE_TEST ) - add_definitions( -D${PROJECT_NAME}_ENABLE_TEST ) + add_compile_definitions( ${PROJECT_NAME}_ENABLE_TEST ) add_subdirectory( ${CMAKE_CURRENT_SOURCE_DIR}/${TEST} ) endif( ${PROJECT_NAME}_ENABLE_TEST ) endmacro() @@ -255,21 +264,6 @@ endmacro() # utilities # ############# -macro(kasper_find_module NAME) - if( ${ARGV1} ) - set( VERSION ${ARGV1} ) - else() - set( VERSION "0" ) - endif() - - find_package( ${NAME} ${VERSION} REQUIRED NO_MODULE ) - #message("${NAME}_INCLUDE_DIRS: ${${NAME}_INCLUDE_DIRS}") - kasper_internal_include_directories( ${${NAME}_INCLUDE_DIRS} ) - #kasper_external_include_directories( ${${NAME}_INCLUDE_DIRS} ) - #set( ${NAME}_INCLUDE_DIRS "${${NAME}_INCLUDE_DIRS}" PARENT_SCOPE ) - -endmacro() - macro(kasper_append_paths PARENT_VAR) foreach(RELPATH ${ARGN}) get_filename_component(ABSPATH ${RELPATH} ABSOLUTE) @@ -323,14 +317,46 @@ macro(kasper_install_headers) install(FILES ${ARGN} DESTINATION ${${PROJECT_NAME}_INCLUDE_INSTALL_DIR}) endmacro() +macro(kasper_install_header_directory) + install(DIRECTORY ${ARGN} DESTINATION ${${PROJECT_NAME}_INCLUDE_INSTALL_DIR}) +endmacro() + macro(kasper_install_libraries) - install(TARGETS ${ARGN} EXPORT KasperTargets DESTINATION ${${PROJECT_NAME}_LIB_INSTALL_DIR}) - set_property(GLOBAL APPEND PROPERTY MODULE_TARGETS ${ARGN}) - set_target_properties(${ARGN} PROPERTIES INSTALL_NAME_DIR ${${PROJECT_NAME}_LIB_INSTALL_DIR}) + install(TARGETS ${ARGN} + EXPORT ${PROJECT_NAME}Targets + DESTINATION ${${PROJECT_NAME}_LIB_INSTALL_DIR} + ) + + foreach(ARG ${ARGN}) + get_target_property(TARGET_TYPE ${ARG} TYPE) + if(NOT ${TARGET_TYPE} STREQUAL INTERFACE_LIBRARY) + set_target_properties(${ARG} PROPERTIES INSTALL_NAME_DIR ${${PROJECT_NAME}_LIB_INSTALL_DIR}) + endif() + + # append to list of project librariers + # TODO: there should be a smarter method to get this directly from the CMake export set... + set_property(GLOBAL APPEND PROPERTY ${PROJECT_NAME}_LIBRARIES ${ARG}) + endforeach() endmacro() macro(kasper_install_executables) - install(TARGETS ${ARGN} EXPORT KasperTargets DESTINATION ${${PROJECT_NAME}_BIN_INSTALL_DIR}) + install(TARGETS ${ARGN} + EXPORT ${PROJECT_NAME}Targets + DESTINATION ${${PROJECT_NAME}_BIN_INSTALL_DIR} + ) +endmacro() + +macro(kasper_install_executables_with_symlinks LINK_NAME) + kasper_install_executables(${ARGN}) + foreach( EXECUTABLE_NAME ${ARGN} ) + set(LINK_TARGET_NAME ${LINK_NAME}${EXECUTABLE_NAME}) + install(CODE "execute_process( \ + COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${${PROJECT_NAME}_BIN_INSTALL_DIR}/${EXECUTABLE_NAME} \ + ${${PROJECT_NAME}_BIN_INSTALL_DIR}/${LINK_TARGET_NAME} \ + )" + ) + endforeach( EXECUTABLE_NAME ) endmacro() macro(kasper_install_script) @@ -358,15 +384,10 @@ macro(kasper_install_files DEST_DIR) endmacro() macro(kasper_install_module) - - configure_file(ModuleConfigVersion.cmake.in ${PROJECT_NAME}ConfigVersion.cmake @ONLY) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_DIR}/${PROJECT_NAME}) - - get_property(MODULE_TARGETS GLOBAL PROPERTY MODULE_TARGETS) - #list(APPEND EXTERNAL_INCLUDE_DIRS ${KASPER_INCLUDE_DIRS}) + kasper_set_version_numbers(MODULE_VERSION) + #message(STATUS "Processed module: ${PROJECT_NAME} v${PROJECT_VERSION}") set(INSTALLED_INCLUDE_DIRS ${INCLUDE_INSTALL_DIR}) - foreach(DIR ${EXTERNAL_INCLUDE_DIRS}) if (NOT ${DIR} STREQUAL "SYSTEM") file(RELATIVE_PATH REL_DIR ${CMAKE_SOURCE_DIR} ${DIR}) @@ -377,45 +398,100 @@ macro(kasper_install_module) endforeach() list(REMOVE_DUPLICATES INSTALLED_INCLUDE_DIRS) - configure_file(ModuleConfigInstalled.cmake.in ${PROJECT_NAME}ConfigInstalled.cmake @ONLY) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigInstalled.cmake DESTINATION ${CMAKE_INSTALL_DIR}/${PROJECT_NAME} - RENAME ${PROJECT_NAME}Config.cmake) - - if(STANDALONE) - install(EXPORT KasperTargets DESTINATION ${CMAKE_INSTALL_DIR} FILE ModuleTargets.cmake) - else() - - set(MODULE_INCLUDE_DIRS ) - set(TMP_DIR_LIST ${MODULE_HEADER_DIRS};${EXTERNAL_INCLUDE_DIRS}) - foreach(DIR ${TMP_DIR_LIST}) - string(REPLACE " " "\\\ " DIR ${DIR}) - list(APPEND MODULE_INCLUDE_DIRS ${DIR}) - endforeach() - - list( LENGTH MODULE_INCLUDE_DIRS LL) - if( LL GREATER 1 ) - list( REMOVE_DUPLICATES MODULE_INCLUDE_DIRS ) - endif() + configure_file(${PROJECT_NAME}ConfigVersion.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake @ONLY) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_DIR}/${PROJECT_NAME} + ) - configure_file(ModuleConfig.cmake.in ${PROJECT_NAME}Config.cmake @ONLY) - endif() + install(EXPORT ${PROJECT_NAME}Targets + NAMESPACE ${PROJECT_NAME}:: + DESTINATION ${CMAKE_INSTALL_DIR}/${PROJECT_NAME} + ) + configure_file(${PROJECT_NAME}Config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake @ONLY) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake + DESTINATION ${CMAKE_INSTALL_DIR}/${PROJECT_NAME} + ) #pkg-config kasper_export_pkgconfig() endmacro() - macro(kasper_export_pkgconfig) - include(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake) + get_property(${PROJECT_NAME}_LIBRARIES GLOBAL PROPERTY ${PROJECT_NAME}_LIBRARIES) + + set(${PROJECT_NAME}_DEPENDS) + set(${PROJECT_NAME}_CXX_FLAGS) + + # generate list of dependencies for installed libraries + foreach(TARGET_NAME ${${PROJECT_NAME}_LIBRARIES}) + get_target_property(TARGET_LIBS ${TARGET_NAME} INTERFACE_LINK_LIBRARIES) + foreach(LIB_NAME ${TARGET_LIBS}) + if(TARGET ${LIB_NAME}) + get_target_property(LIB_TYPE ${LIB_NAME} TYPE) + if(NOT LIB_TYPE STREQUAL INTERFACE_LIBRARY) + get_target_property(LIB_IMPORTED ${LIB_NAME} IMPORTED) + if(LIB_IMPORTED) + # get the actual filename on disk + get_target_property(LIB_LOCATION ${LIB_NAME} LOCATION) + if(LIB_LOCATION) + list(APPEND ${PROJECT_NAME}_DEPENDS ${LIB_LOCATION}) + endif(LIB_LOCATION) + else(LIB_IMPORTED) + list(APPEND ${PROJECT_NAME}_DEPENDS ${LIB_NAME}) + endif(LIB_IMPORTED) + endif() + endif() + endforeach(LIB_NAME) + + get_target_property(TARGET_LINK_OPTS ${TARGET_NAME} INTERFACE_LINK_OPTIONS) + if(TARGET_LINK_OPTS) + foreach(FLAG ${TARGET_LINK_OPTS}) + list(APPEND ${PROJECT_NAME}_DEPENDS ${FLAG}) + endforeach(FLAG) + endif() + + get_target_property(TARGET_OPTS ${TARGET_NAME} INTERFACE_COMPILE_OPTIONS) + if(TARGET_OPTS) + foreach(FLAG ${TARGET_OPTS}) + if(NOT ${FLAG} MATCHES "-W") + list(APPEND ${PROJECT_NAME}_CXX_FLAGS ${FLAG}) + endif() + endforeach(FLAG) + endif(TARGET_OPTS) + + get_target_property(TARGET_DEFS ${TARGET_NAME} INTERFACE_COMPILE_DEFINITIONS) + if(TARGET_DEFS) + foreach(FLAG ${TARGET_DEFS}) + list(APPEND ${PROJECT_NAME}_CXX_FLAGS -D${FLAG}) + endforeach(FLAG) + endif(TARGET_DEFS) + + get_target_property(TARGET_INCLUDE_DIRS ${TARGET_NAME} INTERFACE_INCLUDE_DIRECTORIES) + if(TARGET_INCLUDE_DIRS) + foreach(INC_DIR ${TARGET_INCLUDE_DIRS}) + # ignore cmake generator expressions + if(NOT (${INC_DIR} MATCHES "BUILD_INTERFACE:" OR ${INC_DIR} MATCHES "INSTALL_INTERFACE:")) + list(APPEND ${PROJECT_NAME}_CXX_FLAGS -I${INC_DIR}) + endif() + endforeach(INC_DIR) + endif(TARGET_INCLUDE_DIRS) + + endforeach(TARGET_NAME) + + #message("${PROJECT_NAME}_CXX_FLAGS : ${${PROJECT_NAME}_CXX_FLAGS}") + #message("${PROJECT_NAME}_DEPENDS : ${${PROJECT_NAME}_DEPENDS}") + + #include(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake) set(DESCRIPTION ${ARGV0}) set( PC_LIBRARIES_STR ) set( LIBDIRS ) set( LIBS ${${PROJECT_NAME}_LIBRARIES} ${${PROJECT_NAME}_DEPENDS} ) - list( REMOVE_DUPLICATES LIBS ) - #message("${PROJECT_NAME}: ${LIBS}") + if(LIBS) + list( REMOVE_DUPLICATES LIBS ) + endif(LIBS) foreach(LIB ${LIBS}) @@ -448,45 +524,52 @@ macro(kasper_export_pkgconfig) endif() endforeach() - set( PC_LD_FLAGS "-L\${libdir}" ) - if( GCC_FORCE_LINKING ) - set( PC_LD_FLAGS "${PC_LD_FLAGS} -Wl,--no-as-needed" ) - endif() + set( PC_LD_FLAGS_STR "-L\${libdir}" ) + #if(GCC_FORCE_LINKING) + # set( PC_LD_FLAGS_STR "${PC_LD_FLAGS_STR} -Wl,--no-as-needed" ) + #endif(GCC_FORCE_LINKING) set( PC_RPATH_STR "\${libdir}" ) foreach(LIBDIR ${LIBDIRS}) - set ( PC_LD_FLAGS "${PC_LD_FLAGS} -L${LIBDIR}" ) + set ( PC_LD_FLAGS_STR "${PC_LD_FLAGS_STR} -L${LIBDIR}" ) set ( PC_RPATH_STR "${PC_RPATH_STR} ${LIBDIR}" ) - endforeach() - - set( PC_LIBRARIES_STR "${PC_LD_FLAGS} ${PC_LIBRARIES_STR}" ) + endforeach(LIBDIR) set( PC_INCLUDE_DIR_STR "-I\${includedir}" ) foreach(DIR ${INSTALLED_INCLUDE_DIRS}) if(NOT DIR STREQUAL INCLUDE_INSTALL_DIR) set ( PC_INCLUDE_DIR_STR "${PC_INCLUDE_DIR_STR} -I${DIR}" ) endif() - endforeach() + endforeach(DIR) + + set( PC_CXX_FLAGS_STR ) + set( CXX_FLAGS ${${PROJECT_NAME}_CXX_FLAGS} ) + if(CXX_FLAGS) + list( REMOVE_DUPLICATES CXX_FLAGS ) + endif(CXX_FLAGS) + foreach(FLAG ${CXX_FLAGS}) + set ( PC_CXX_FLAGS_STR "${PC_CXX_FLAGS_STR} ${FLAG}" ) + endforeach(FLAG) - GET_PROPERTY(GLOBAL_CXX11_FLAG GLOBAL PROPERTY CXX11_FLAG) + GET_PROPERTY(GLOBAL_CXX14_FLAG GLOBAL PROPERTY CXX14_FLAG) set( LINKER_FLAGS ) - if ("${CMAKE_EXE_LINKER_FLAGS}" MATCHES "--no-as-needed") - set( LINKER_FLAGS "-Wl,--no-as-needed") - endif() + #if ("${CMAKE_EXE_LINKER_FLAGS}" MATCHES "--no-as-needed") + # set( LINKER_FLAGS "-Wl,--no-as-needed") + #endif() set( PC_CONTENTS "prefix=${KASPER_INSTALL_DIR} - exec_prefix=${BIN_INSTALL_DIR} - libdir=${LIB_INSTALL_DIR} - includedir=${INCLUDE_INSTALL_DIR} +exec_prefix=${BIN_INSTALL_DIR} +libdir=${LIB_INSTALL_DIR} +includedir=${INCLUDE_INSTALL_DIR} rpath=${PC_RPATH_STR} Name: ${PROJECT_NAME} Description: ${DESCRIPTION} Version: ${MODULE_VERSION} -Libs: ${PC_LIBRARIES_STR} ${LINKER_FLAGS} -Cflags: ${GLOBAL_CXX11_FLAG} ${PC_INCLUDE_DIR_STR} +Libs: ${LINKER_FLAGS} ${PC_LD_FLAGS_STR} ${PC_LIBRARIES_STR} +Cflags: ${GLOBAL_CXX14_FLAG} ${PC_INCLUDE_DIR_STR} ${PC_CXX_FLAGS_STR} ") string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWER ) file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME_LOWER}.pc ${PC_CONTENTS}) @@ -496,7 +579,6 @@ Cflags: ${GLOBAL_CXX11_FLAG} ${PC_INCLUDE_DIR_STR} endmacro() - macro(kasper_add_doc_reference DOXYGEN_FILE) # Builds in the source tree (to instead build in the binary tree, switch CMAKE_CURRENT_SOURCE_DIR to CMAKE_CURRENT_BINARY_DIR in the line that starts with WORKING_DIRECTORY. # This is intended for use by developers only when updating the reference documentation. @@ -595,101 +677,3 @@ endmacro() macro(kasper_install_doc) install(FILES ${ARGN} DESTINATION ${DOC_INSTALL_DIR}/${PROJECT_NAME}) endmacro() - - -# macros to facilitate a modular build via subdirectories - -macro( kasper_include_directories ) - - set(KASPER_DIRS) - set(SYSTEM_DIRS) - - foreach(dir ${ARGN}) - string(FIND ${dir} ${CMAKE_SOURCE_DIR} pos) - if(pos LESS 0) - list(APPEND SYSTEM_DIRS ${dir}) - else() - list(APPEND KASPER_DIRS ${dir}) - endif() - endforeach() - - include_directories( ${KASPER_DIRS} ) - include_directories( SYSTEM;${SYSTEM_DIRS} ) -endmacro() - -macro( kasper_include_default_dirs ) - kasper_include_directories( ${MODULE_HEADER_DIRS};${EXTERNAL_INCLUDE_DIRS} ) -endmacro() - -macro( kasper_internal_include_directories ) - - foreach(dir ${ARGN}) - #message("${dir}") - if(NOT IS_ABSOLUTE ${dir}) - set(dir ${CMAKE_CURRENT_SOURCE_DIR}/${dir}) - endif() - list(APPEND MODULE_HEADER_DIRS ${dir}) - endforeach() - - list( LENGTH MODULE_HEADER_DIRS LL) - if( LL GREATER 1 ) - list( REMOVE_DUPLICATES MODULE_HEADER_DIRS ) - endif() - - if (CMAKE_CURRENT_SOURCE_DIR STRGREATER PROJECT_SOURCE_DIR) - set (MODULE_HEADER_DIRS ${MODULE_HEADER_DIRS} PARENT_SCOPE) - endif() - - kasper_include_directories( ${MODULE_HEADER_DIRS} ) - -endmacro() - - -macro( kasper_external_include_directories ) - - list( APPEND EXTERNAL_INCLUDE_DIRS ${ARGN} ) - - list( LENGTH EXTERNAL_INCLUDE_DIRS LL) - if( LL GREATER 1 ) - list( REMOVE_ITEM EXTERNAL_INCLUDE_DIRS SYSTEM ) - list( REMOVE_DUPLICATES EXTERNAL_INCLUDE_DIRS ) - endif() - - if (CMAKE_CURRENT_SOURCE_DIR STRGREATER PROJECT_SOURCE_DIR) - #message("CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR} -- PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}") - set( EXTERNAL_INCLUDE_DIRS ${EXTERNAL_INCLUDE_DIRS} PARENT_SCOPE ) - endif() - - kasper_include_directories( ${ARGN} ) - -endmacro() - -macro (add_cflag CFLAG) - list (APPEND MODULE_CFLAGS ${CFLAG}) - set (MODULE_CFLAGS ${MODULE_CFLAGS} PARENT_SCOPE) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${CFLAG}") - set (CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} PARENT_SCOPE) -endmacro() - -macro(kasper_find_vtk) - # VTK versions below 6.0.1 do not compile with c++11 support - find_package( VTK REQUIRED NO_MODULE ) - include(${VTK_USE_FILE}) - - if(${VTK_VERSION} VERSION_LESS "6.0.1") - message(FATAL_ERROR "At least VTK version 6.0.1 is required for C++11 support.") - endif() - - if(VTK_VERSION VERSION_GREATER "6" AND VTK_QT_VERSION VERSION_GREATER "4") - find_package(Qt5Widgets QUIET) - endif() - - # VTK_INCLUDE_DIRS is sometimes incorrect (e.g. on Kalinka) - if(EXISTS "/usr/include/vtk") - list(APPEND VTK_INCLUDE_DIRS "/usr/include/vtk") - endif() - if(EXISTS "/usr/local/include/vtk") - list(APPEND VTK_INCLUDE_DIRS "/usr/local/include/vtk") - endif() - kasper_external_include_directories( ${VTK_INCLUDE_DIRS} ) -endmacro() diff --git a/Kommon/cmake/LibFindMacros.cmake b/Kommon/cmake/LibFindMacros.cmake deleted file mode 100644 index ff9233a6c..000000000 --- a/Kommon/cmake/LibFindMacros.cmake +++ /dev/null @@ -1,98 +0,0 @@ -# Works the same as find_package, but forwards the "REQUIRED" and "QUIET" arguments -# used for the current package. For this to work, the first parameter must be the -# prefix of the current package, then the prefix of the new package etc, which are -# passed to find_package. -macro (libfind_package PREFIX) - set (LIBFIND_PACKAGE_ARGS ${ARGN}) - if (${PREFIX}_FIND_QUIETLY) - set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} QUIET) - endif (${PREFIX}_FIND_QUIETLY) - if (${PREFIX}_FIND_REQUIRED) - set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} REQUIRED) - endif (${PREFIX}_FIND_REQUIRED) - find_package(${LIBFIND_PACKAGE_ARGS}) -endmacro (libfind_package) - -# CMake developers made the UsePkgConfig system deprecated in the same release (2.6) -# where they added pkg_check_modules. Consequently I need to support both in my scripts -# to avoid those deprecated warnings. Here's a helper that does just that. -# Works identically to pkg_check_modules, except that no checks are needed prior to use. -macro (libfind_pkg_check_modules PREFIX PKGNAME) - if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4) - include(UsePkgConfig) - pkgconfig(${PKGNAME} ${PREFIX}_INCLUDE_DIRS ${PREFIX}_LIBRARY_DIRS ${PREFIX}_LDFLAGS ${PREFIX}_CFLAGS) - else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4) - find_package(PkgConfig) - if (PKG_CONFIG_FOUND) - pkg_check_modules(${PREFIX} ${PKGNAME}) - endif (PKG_CONFIG_FOUND) - endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4) -endmacro (libfind_pkg_check_modules) - -# Do the final processing once the paths have been detected. -# If include dirs are needed, ${PREFIX}_PROCESS_INCLUDES should be set to contain -# all the variables, each of which contain one include directory. -# Ditto for ${PREFIX}_PROCESS_LIBS and library files. -# Will set ${PREFIX}_FOUND, ${PREFIX}_INCLUDE_DIRS and ${PREFIX}_LIBRARIES. -# Also handles errors in case library detection was required, etc. -macro (libfind_process PREFIX) - # Skip processing if already processed during this run - if (NOT ${PREFIX}_FOUND) - # Start with the assumption that the library was found - set (${PREFIX}_FOUND TRUE) - - # Process all includes and set _FOUND to false if any are missing - foreach (i ${${PREFIX}_PROCESS_INCLUDES}) - if (${i}) - set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIRS} ${${i}}) - mark_as_advanced(${i}) - else (${i}) - set (${PREFIX}_FOUND FALSE) - endif (${i}) - endforeach (i) - - # Process all libraries and set _FOUND to false if any are missing - foreach (i ${${PREFIX}_PROCESS_LIBS}) - if (${i}) - set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARIES} ${${i}}) - mark_as_advanced(${i}) - else (${i}) - set (${PREFIX}_FOUND FALSE) - endif (${i}) - endforeach (i) - - # Print message and/or exit on fatal error - if (${PREFIX}_FOUND) - if (NOT ${PREFIX}_FIND_QUIETLY) - message (STATUS "Found ${PREFIX} ${${PREFIX}_VERSION}") - endif (NOT ${PREFIX}_FIND_QUIETLY) - else (${PREFIX}_FOUND) - if (${PREFIX}_FIND_REQUIRED) - foreach (i ${${PREFIX}_PROCESS_INCLUDES} ${${PREFIX}_PROCESS_LIBS}) - message("${i}=${${i}}") - endforeach (i) - message (FATAL_ERROR "Required library ${PREFIX} NOT FOUND.\nInstall the library (dev version) and try again. If the library is already installed, use ccmake to set the missing variables manually.") - endif (${PREFIX}_FIND_REQUIRED) - endif (${PREFIX}_FOUND) - endif (NOT ${PREFIX}_FOUND) -endmacro (libfind_process) - -macro(libfind_library PREFIX basename) - set(TMP "") - if(MSVC80) - set(TMP -vc80) - endif(MSVC80) - if(MSVC90) - set(TMP -vc90) - endif(MSVC90) - set(${PREFIX}_LIBNAMES ${basename}${TMP}) - if(${ARGC} GREATER 2) - set(${PREFIX}_LIBNAMES ${basename}${TMP}-${ARGV2}) - string(REGEX REPLACE "\\." "_" TMP ${${PREFIX}_LIBNAMES}) - set(${PREFIX}_LIBNAMES ${${PREFIX}_LIBNAMES} ${TMP}) - endif(${ARGC} GREATER 2) - find_library(${PREFIX}_LIBRARY - NAMES ${${PREFIX}_LIBNAMES} - PATHS ${${PREFIX}_PKGCONF_LIBRARY_DIRS} - ) -endmacro(libfind_library) diff --git a/Kommon/cmake/MacroCheckPackageLibs.cmake b/Kommon/cmake/MacroCheckPackageLibs.cmake deleted file mode 100644 index 0f9050d5d..000000000 --- a/Kommon/cmake/MacroCheckPackageLibs.cmake +++ /dev/null @@ -1,163 +0,0 @@ -############################################################################## -# macro for checkin package libraries in ${PKG_ROOT}/lib -# -# -# macro usage: -# CHECK_PACKAGE_LIBS( PACKAGE_NAME stdlib1 stdlib2 ... stdlibn ) -# only standard libraries should be passed as arguments to the macro -# component libraries are set by cmake in PKG_FIND_COMPONENTS (when -# calling FIND_PACKAGE with COMPONENTS argument) or through the -# variable PKG_USE_COMPONENTS -# -# -# required variables: -# PKG_ROOT : path to PKG root directory -# -# -# returns following variables: -# PKG_LIBRARY_DIRS : list of paths to be used with LINK_DIRECTORIES -# PGK_LIBRARIES : list of STANDARD libraries (NOT including COMPONENTS) -# PKG_COMPONENT_LIBRARIES : list of COMPONENT libraries -# PKG_${COMPONENT}_FOUND : set to TRUE or FALSE for each library -# PKG_${COMPONENT}_LIBRARY : path to each individual library -# -# -# PKG_LIBRARIES and PKG_LIBRARY_DIRS will be empty if any of the standard -# libraries is missing -# -# @author Jan Engels, Desy -############################################################################## - - -SET( CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS TRUE ) - -MACRO( CHECK_PACKAGE_LIBS _pkgname ) - - SET( _std_lib_missing FALSE ) - SET( _ext_lib_missing FALSE ) - - SET( _std_libnames ${ARGN} ) - SET( _ext_libnames ${${_pkgname}_FIND_COMPONENTS} ${${_pkgname}_USE_COMPONENTS} ) - - IF( _ext_libnames ) - SEPARATE_ARGUMENTS( _ext_libnames ) - LIST( REMOVE_DUPLICATES _ext_libnames ) - ENDIF() - - IF( NOT ${_pkgname}_FIND_QUIETLY ) - MESSAGE( STATUS "Check for ${_pkgname}_LIBRARIES: ${_std_libnames}" ) - IF( _ext_libnames ) - MESSAGE( STATUS "Check for ${_pkgname}_COMPONENT_LIBRARIES: ${_ext_libnames}" ) - ENDIF() - ENDIF() - - SET( ${_pkgname}_LIBRARY_DIRS ) - MARK_AS_ADVANCED( ${_pkgname}_LIBRARY_DIRS ) - - SET( ${_pkgname}_LIBRARIES ) - MARK_AS_ADVANCED( ${_pkgname}_LIBRARIES ) - - SET( ${_pkgname}_COMPONENT_LIBRARIES ) - MARK_AS_ADVANCED( ${_pkgname}_COMPONENT_LIBRARIES ) - - SET( ${_pkgname}_COMPONENT_VARIABLES ) - MARK_AS_ADVANCED( ${_pkgname}_COMPONENT_VARIABLES ) - - FOREACH( _libname ${_std_libnames} ${_ext_libnames} ) - - # flag to check if it is a standard or a component library - LIST( FIND _std_libnames "${_libname}" _aux ) - IF( ${_aux} LESS 0 ) - SET( _is_std_lib FALSE ) - ELSE() - SET( _is_std_lib TRUE ) - ENDIF() - - # libname in upper case - STRING( TOUPPER ${_libname} _ulibname ) - - SET( ${_pkgname}_${_ulibname}_LIBRARY ${_pkgname}_${_ulibname}_LIBRARY-NOTFOUND ) - MARK_AS_ADVANCED( ${_pkgname}_${_ulibname}_LIBRARY ) - - # WARNING: using PATH_SUFFIXES may cause problems when using variable CMAKE_FIND_ROOT_PATH - # this problem does not occur if expanding PATHS - # look in FindMySQL.cmake for more info - #FIND_LIBRARY( ${_pkgname}_${_ulibname}_LIBRARY NAMES ${_libname} PATHS - # ${${_pkgname}_ROOT} ${${_pkgname}_DIR} ${${_pkgname}_LIB_SEARCH_PATH} - # PATH_SUFFIXES lib64 lib - # NO_DEFAULT_PATH - #) - - FIND_LIBRARY( ${_pkgname}_${_ulibname}_LIBRARY NAMES ${_libname} PATHS - ${${_pkgname}_ROOT}/lib64 ${${_pkgname}_ROOT}/lib - ${${_pkgname}_DIR}/lib64 ${${_pkgname}_DIR}/lib - ${${_pkgname}_LIB_SEARCH_PATH} ${${_pkgname}_LIB_SEARCH_PATH}/lib64 ${${_pkgname}_LIB_SEARCH_PATH}/lib - NO_DEFAULT_PATH - ) - - IF( NOT ${_pkgname}_DIR ) - FIND_LIBRARY( ${_pkgname}_${_ulibname}_LIBRARY NAMES ${_libname} ) - ENDIF() - - IF( ${_pkgname}_FIND_REQUIRED ) - LIST( APPEND ${_pkgname}_COMPONENT_VARIABLES ${_pkgname}_${_ulibname}_LIBRARY ) - ENDIF() - - IF( ${_pkgname}_${_ulibname}_LIBRARY ) # if library found - - SET( ${_pkgname}_${_ulibname}_FOUND TRUE ) - - # split libraries in PKG_LIBRARIES and PKG_COMPONENT_LIBRARIES - IF( _is_std_lib ) - LIST( APPEND ${_pkgname}_LIBRARIES ${${_pkgname}_${_ulibname}_LIBRARY} ) - ELSE() - LIST( APPEND ${_pkgname}_COMPONENT_LIBRARIES ${${_pkgname}_${_ulibname}_LIBRARY} ) - ENDIF() - - GET_FILENAME_COMPONENT( _aux ${${_pkgname}_${_ulibname}_LIBRARY} PATH ) - LIST( APPEND ${_pkgname}_LIBRARY_DIRS ${_aux} ) - - IF( NOT ${_pkgname}_FIND_QUIETLY ) - MESSAGE( STATUS "Check for ${_pkgname}_${_ulibname}_LIBRARY: ${${_pkgname}_${_ulibname}_LIBRARY} -- ok" ) - ENDIF() - - ELSE() # library not found - - SET( ${_pkgname}_${_ulibname}_FOUND FALSE ) - - IF( _is_std_lib ) - SET( _std_lib_missing TRUE ) - ELSE() - SET( _ext_lib_missing TRUE ) - ENDIF() - - IF( NOT ${_pkgname}_FIND_QUIETLY ) - MESSAGE( STATUS "Check for ${_pkgname}_${_ulibname}_LIBRARY: ${_libname} -- failed" ) - ENDIF() - - ENDIF() - - ENDFOREACH() - - # clear PKG_LIBRARIES if standard library is missing - IF( _std_lib_missing ) - SET( ${_pkgname}_LIBRARIES ) - ENDIF() - - # clear PKG_COMPONENT_LIBRARIES if a component library is missing and - # FIND_PACKAGE called with REQUIRED argument - IF( _ext_lib_missing AND ${_pkgname}_FIND_REQUIRED ) - SET( ${_pkgname}_COMPONENT_LIBRARIES ) - ENDIF() - - # remove duplicate paths in PKG_LIBRARY_DIRS - IF( ${_pkgname}_LIBRARY_DIRS ) - LIST( REMOVE_DUPLICATES ${_pkgname}_LIBRARY_DIRS ) - ENDIF() - - # debug - #MESSAGE( STATUS "${_pkgname}_LIBRARIES: ${${_pkgname}_LIBRARIES}" ) - #MESSAGE( STATUS "${_pkgname}_COMPONENT_LIBRARIES: ${${_pkgname}_COMPONENT_LIBRARIES}" ) - #MESSAGE( STATUS "${_pkgname}_LIBRARY_DIRS: ${${_pkgname}_LIBRARY_DIRS}" ) - -ENDMACRO( CHECK_PACKAGE_LIBS _pkgname ) diff --git a/Kommon/cmake/MacroCheckPackageVersion.cmake b/Kommon/cmake/MacroCheckPackageVersion.cmake deleted file mode 100644 index e3ec75d9f..000000000 --- a/Kommon/cmake/MacroCheckPackageVersion.cmake +++ /dev/null @@ -1,108 +0,0 @@ -############################################################################## -# macro for checking a package version -# -# this macro should be called from your PKGVersion.cmake or from a -# FindPKG.cmake module with the following arguments: -# _pkgname : The package name -# _iversion : The installed version of the package -# -# -# the following conventions are used: -# -# if FIND_PACKAGE is called with EXACT argument than the version has to -# match EXACTLY, i.e.: -# 1.5 == 1.5 -# 1.5 == 1.5.0 -# 1.5 == 1.5.0.0 -# 1.5.2 == 1.5.2.0 -# 1.5.2.1 == 1.5.2.1 -# 1.5.2 != 1.5.2.1 -# 1.5 != 1.5.0.1 -# -# -# otherwise a MINIMUM_REQUIRED version is checked for, i.e. the same -# behavior as with the cmake variable CMAKE_MINIMUM_REQUIRED, e.g.: -# searching: 1.2 --> installed: 1.5.2.2 --> compatible -# searching: 1.5 --> installed: 1.5.2.2 --> compatible -# searching: 1.5.2.1 --> installed: 1.5.2.2 --> compatible -# searching: 1.5.2.3 --> installed: 1.5.2.2 --> unsuitable -# searching: 1.7 --> installed: 1.5.2.2 --> unsuitable -# -# -# following variables are returned (internally to cmake): -# PACKAGE_VERSION_EXACT : set to TRUE if exact version was found -# PACKAGE_VERSION_COMPATIBLE : set to TRUE if version is compatible -# PACKAGE_VERSION_UNSUITABLE : set to TRUE if version found is unsuitable -# -# -# @author Jan Engels, Desy IT -############################################################################## - -# these variables are evaluated internally by the cmake command FIND_PACKAGE to mark this -# package as suitable or not depending on the required version -SET( PACKAGE_VERSION_EXACT FALSE ) -SET( PACKAGE_VERSION_COMPATIBLE TRUE ) -SET( PACKAGE_VERSION_UNSUITABLE FALSE ) - - -# cmake internal variable PACKAGE_FIND_NAME is not defined on FindPKG.cmake -# modules, therefore it is passed as an argument to the macro -# _iversion is the installed version of the package -# _sversion is the version searched by the user with FIND_PACKAGE -#MACRO( CHECK_PACKAGE_VERSION _pkgname _iversion ) -MACRO( CHECK_PACKAGE_VERSION _pkgname ) # left with one argument only for backwards compatibility - - IF( NOT "${ARGV1}" STREQUAL "" ) - SET( _iversion ${ARGV1} ) - ELSE() - SET( _iversion ${${_pkgname}_VERSION_MAJOR}.${${_pkgname}_VERSION_MINOR}.${${_pkgname}_VERSION_PATCH}.${${_pkgname}_VERSION_TWEAK} ) - ENDIF() - - #SET( _sversion_major ${${_pkgname}_FIND_VERSION_MAJOR} ) - #SET( _sversion_minor ${${_pkgname}_FIND_VERSION_MINOR} ) - - SET( _sversion ${${_pkgname}_FIND_VERSION} ) - - IF( NOT ${_pkgname}_FIND_QUIETLY ) - MESSAGE( STATUS "Check for ${_pkgname} (${_iversion})" ) - ENDIF() - - # only do work if FIND_PACKAGE called with a version argument - IF( _sversion ) - - #IF( NOT ${_pkgname}_FIND_QUIETLY ) - # MESSAGE( STATUS "Check for ${_pkgname}: looking for version ${_sversion}" ) - #ENDIF() - - IF( ${_iversion} VERSION_EQUAL ${_sversion} ) # if version matches EXACTLY - #IF( NOT ${_pkgname}_FIND_QUIETLY ) - # MESSAGE( STATUS "Check for ${_pkgname}: exact version found: ${_iversion}" ) - #ENDIF() - SET( PACKAGE_VERSION_EXACT TRUE ) - ELSE() # if version does not match EXACTLY, check if it is compatible/suitable - - # installed version must be greater or equal than version searched by the user, i.e. - # like with the CMAKE_MINIMUM_REQUIRED commando - # if user asks for version 1.2.5 then any version >= 1.2.5 is suitable/compatible - IF( NOT ${_sversion} VERSION_LESS ${_iversion} ) - SET( PACKAGE_VERSION_UNSUITABLE TRUE ) - ENDIF() - # ------------------------------------------------------------------------------------- - - IF( ${_pkgname}_FIND_VERSION_EXACT ) # if exact version was required search must fail!! - #IF( NOT ${_pkgname}_FIND_QUIETLY ) - # MESSAGE( "Check for ${_pkgname}: could not find exact version" ) - #ENDIF() - SET( PACKAGE_VERSION_UNSUITABLE TRUE ) - ENDIF() - - ENDIF() - - IF( PACKAGE_VERSION_UNSUITABLE ) - SET( PACKAGE_VERSION_COMPATIBLE FALSE ) - ENDIF() - - ENDIF( _sversion ) - -ENDMACRO( CHECK_PACKAGE_VERSION ) - diff --git a/Kommon/cmake/ModuleConfig.cmake.in b/Kommon/cmake/ModuleConfig.cmake.in new file mode 100644 index 000000000..ebaf9b526 --- /dev/null +++ b/Kommon/cmake/ModuleConfig.cmake.in @@ -0,0 +1,3 @@ +if(NOT TARGET @PROJECT_NAME@::@PROJECT_NAME@) + include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +endif() diff --git a/KEMField/ModuleConfigVersion.cmake.in b/Kommon/cmake/ModuleConfigVersion.cmake.in similarity index 95% rename from KEMField/ModuleConfigVersion.cmake.in rename to Kommon/cmake/ModuleConfigVersion.cmake.in index 8dff079d1..25f052f29 100644 --- a/KEMField/ModuleConfigVersion.cmake.in +++ b/Kommon/cmake/ModuleConfigVersion.cmake.in @@ -1,7 +1,5 @@ -# $Id: $ - set(PACKAGE_VERSION "@MODULE_VERSION@") - + # Check whether the requested PACKAGE_FIND_VERSION is compatible if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") set(PACKAGE_VERSION_COMPATIBLE FALSE) @@ -10,4 +8,4 @@ else() if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") set(PACKAGE_VERSION_EXACT TRUE) endif() -endif() \ No newline at end of file +endif() diff --git a/Kommon/cmake/OptimizeForArchitecture.cmake b/Kommon/cmake/OptimizeForArchitecture.cmake deleted file mode 100644 index 610078860..000000000 --- a/Kommon/cmake/OptimizeForArchitecture.cmake +++ /dev/null @@ -1,438 +0,0 @@ -INCLUDE (CheckCXXSourceCompiles) -INCLUDE (CheckCSourceCompiles) - -MACRO(NORMALIZE_VERSION _requested_version _normalized_version) - STRING(REGEX MATCH "[^0-9]*[0-9]+\\.[0-9]+\\.[0-9]+.*" _threePartMatch "${_requested_version}") - if (_threePartMatch) - # parse the parts of the version string - STRING(REGEX REPLACE "[^0-9]*([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" _major_vers "${_requested_version}") - STRING(REGEX REPLACE "[^0-9]*[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" _minor_vers "${_requested_version}") - STRING(REGEX REPLACE "[^0-9]*[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" _patch_vers "${_requested_version}") - else (_threePartMatch) - STRING(REGEX REPLACE "([0-9]+)\\.[0-9]+" "\\1" _major_vers "${_requested_version}") - STRING(REGEX REPLACE "[0-9]+\\.([0-9]+)" "\\1" _minor_vers "${_requested_version}") - set(_patch_vers "0") - endif (_threePartMatch) - - # compute an overall version number which can be compared at once - MATH(EXPR ${_normalized_version} "${_major_vers}*10000 + ${_minor_vers}*100 + ${_patch_vers}") -ENDMACRO(NORMALIZE_VERSION) - -MACRO(MACRO_CHECK_RANGE_INCLUSIVE_LOWER _lower_limit _value _upper_limit _ok) - if (${_value} LESS ${_lower_limit}) - set( ${_ok} FALSE ) - elseif (${_value} EQUAL ${_lower_limit}) - set( ${_ok} TRUE ) - elseif (${_value} EQUAL ${_upper_limit}) - set( ${_ok} FALSE ) - elseif (${_value} GREATER ${_upper_limit}) - set( ${_ok} FALSE ) - else (${_value} LESS ${_lower_limit}) - set( ${_ok} TRUE ) - endif (${_value} LESS ${_lower_limit}) -ENDMACRO(MACRO_CHECK_RANGE_INCLUSIVE_LOWER) - -MACRO(MACRO_ENSURE_VERSION requested_version found_version var_too_old) - NORMALIZE_VERSION( ${requested_version} req_vers_num ) - NORMALIZE_VERSION( ${found_version} found_vers_num ) - - if (found_vers_num LESS req_vers_num) - set( ${var_too_old} FALSE ) - else (found_vers_num LESS req_vers_num) - set( ${var_too_old} TRUE ) - endif (found_vers_num LESS req_vers_num) - -ENDMACRO(MACRO_ENSURE_VERSION) - -MACRO(MACRO_ENSURE_VERSION2 requested_version2 found_version2 var_too_old2) - MACRO_ENSURE_VERSION( ${requested_version2} ${found_version2} ${var_too_old2}) -ENDMACRO(MACRO_ENSURE_VERSION2) - -MACRO(MACRO_ENSURE_VERSION_RANGE min_version found_version max_version var_ok) - NORMALIZE_VERSION( ${min_version} req_vers_num ) - NORMALIZE_VERSION( ${found_version} found_vers_num ) - NORMALIZE_VERSION( ${max_version} max_vers_num ) - - MACRO_CHECK_RANGE_INCLUSIVE_LOWER( ${req_vers_num} ${found_vers_num} ${max_vers_num} ${var_ok}) -ENDMACRO(MACRO_ENSURE_VERSION_RANGE) - -MACRO (CHECK_CXX_COMPILER_FLAG _FLAG _RESULT) - SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}") - SET(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}") - CHECK_CXX_SOURCE_COMPILES("int main() { return 0;}" ${_RESULT} - # Some compilers do not fail with a bad flag - FAIL_REGEX "is valid for .* but not for C\\\\+\\\\+" # GNU - FAIL_REGEX "unrecognized .*option" # GNU - FAIL_REGEX "ignoring unknown option" # MSVC - FAIL_REGEX "[Uu]nknown option" # HP - FAIL_REGEX "[Ww]arning: [Oo]ption" # SunPro - FAIL_REGEX "command option .* is not recognized" # XL - FAIL_REGEX "WARNING: unknown flag:" # Open64 - ) - SET (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}") -ENDMACRO (CHECK_CXX_COMPILER_FLAG) - -MACRO (CHECK_C_COMPILER_FLAG _FLAG _RESULT) - SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}") - SET(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}") - CHECK_C_SOURCE_COMPILES("int main() { return 0;}" ${_RESULT} - # Some compilers do not fail with a bad flag - FAIL_REGEX "is valid for .* but not for C" # GNU - FAIL_REGEX "unrecognized .*option" # GNU - FAIL_REGEX "ignoring unknown option" # MSVC - FAIL_REGEX "[Uu]nknown option" # HP - FAIL_REGEX "[Ww]arning: [Oo]ption" # SunPro - FAIL_REGEX "command option .* is not recognized" # XL - FAIL_REGEX "WARNING: unknown flag:" # Open64 - ) - SET (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}") -ENDMACRO (CHECK_C_COMPILER_FLAG) - -macro(AddCompilerFlag _flag) - string(REGEX REPLACE "[+/:= ]" "_" _flag_esc "${_flag}") - check_c_compiler_flag("${_flag}" check_c_compiler_flag_${_flag_esc}) - check_cxx_compiler_flag("${_flag}" check_cxx_compiler_flag_${_flag_esc}) - if(check_c_compiler_flag_${_flag_esc}) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_flag}") - endif(check_c_compiler_flag_${_flag_esc}) - if(check_cxx_compiler_flag_${_flag_esc}) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_flag}") - endif(check_cxx_compiler_flag_${_flag_esc}) - if(${ARGC} EQUAL 2) - set(${ARGV1} "${check_cxx_compiler_flag_${_flag_esc}}") - endif(${ARGC} EQUAL 2) -endmacro(AddCompilerFlag) - -macro(_my_find _list _value _ret) - list(FIND ${_list} "${_value}" _found) - if(_found EQUAL -1) - set(${_ret} FALSE) - else(_found EQUAL -1) - set(${_ret} TRUE) - endif(_found EQUAL -1) -endmacro(_my_find) - -macro(OptimizeForArchitecture) - set(TARGET_ARCHITECTURE "auto" CACHE STRING "CPU architecture to optimize for. Using an incorrect setting here can result in crashes of the resulting binary because of invalid instructions used.\nSetting the value to \"auto\" will try to optimize for the architecture where cmake is called.\nOther supported values are: \"generic\", \"core\", \"merom\" (65nm Core2), \"penryn\" (45nm Core2), \"nehalem\", \"westmere\", \"sandy-bridge\", \"atom\", \"k8\", \"k8-sse3\", \"barcelona\", \"istanbul\", \"magny-cours\", \"bulldozer\", \"interlagos\".") - set(_force) - if(NOT _last_target_arch STREQUAL "${TARGET_ARCHITECTURE}") - message(STATUS "${TARGET_ARCHITECTURE} changed") - set(_force FORCE) - endif(NOT _last_target_arch STREQUAL "${TARGET_ARCHITECTURE}") - set(_last_target_arch "${TARGET_ARCHITECTURE}" CACHE STRING "" FORCE) - mark_as_advanced(_last_target_arch) - string(TOLOWER "${TARGET_ARCHITECTURE}" TARGET_ARCHITECTURE) - - set(_march_flag_list) - set(_available_vector_units_list) - - if(TARGET_ARCHITECTURE STREQUAL "auto") - set(TARGET_ARCHITECTURE "generic") - set(_vendor_id) - set(_cpu_family) - set(_cpu_model) - if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - file(READ "/proc/cpuinfo" _cpuinfo) - string(REGEX REPLACE ".*vendor_id[ \t]*:[ \t]+([a-zA-Z0-9_-]+).*" "\\1" _vendor_id "${_cpuinfo}") - string(REGEX REPLACE ".*cpu family[ \t]*:[ \t]+([a-zA-Z0-9_-]+).*" "\\1" _cpu_family "${_cpuinfo}") - string(REGEX REPLACE ".*model[ \t]*:[ \t]+([a-zA-Z0-9_-]+).*" "\\1" _cpu_model "${_cpuinfo}") - string(REGEX REPLACE ".*flags[ \t]*:[ \t]+([a-zA-Z0-9_-]+).*" "\\1" _cpu_flags "${_cpuinfo}") - elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") - exec_program("/usr/sbin/sysctl -n machdep.cpu.vendor" OUTPUT_VARIABLE _vendor_id) - exec_program("/usr/sbin/sysctl -n machdep.cpu.model" OUTPUT_VARIABLE _cpu_model) - exec_program("/usr/sbin/sysctl -n machdep.cpu.family" OUTPUT_VARIABLE _cpu_family) - exec_program("/usr/sbin/sysctl -n machdep.cpu.features" OUTPUT_VARIABLE _cpu_flags) - string(TOLOWER "${_cpu_flags}" _cpu_flags) - string(REPLACE "." "_" _cpu_flags "${_cpu_flags}") - elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") - get_filename_component(_vendor_id "[HKEY_LOCAL_MACHINE\\Hardware\\Description\\System\\CentralProcessor\\0;VendorIdentifier]" NAME CACHE) - get_filename_component(_cpu_id "[HKEY_LOCAL_MACHINE\\Hardware\\Description\\System\\CentralProcessor\\0;Identifier]" NAME CACHE) - mark_as_advanced(_vendor_id _cpu_id) - string(REGEX REPLACE ".* Family ([0-9]+) .*" "\\1" _cpu_family "${_cpu_id}") - string(REGEX REPLACE ".* Model ([0-9]+) .*" "\\1" _cpu_model "${_cpu_id}") - message(AUTHOR_WARNING "If you know how to query the processor capabilities wrt. SSE on Windows, let me know!") - endif(CMAKE_SYSTEM_NAME STREQUAL "Linux") - if(_vendor_id STREQUAL "GenuineIntel") - if(_cpu_family EQUAL 6) - # Any recent Intel CPU except NetBurst - if(_cpu_model EQUAL 46) # Xeon 7500 series - set(TARGET_ARCHITECTURE "westmere") - elseif(_cpu_model EQUAL 45) # Xeon TNG - set(TARGET_ARCHITECTURE "sandy-bridge") - elseif(_cpu_model EQUAL 44) # Xeon 5600 series - set(TARGET_ARCHITECTURE "westmere") - elseif(_cpu_model EQUAL 42) # Core TNG - set(TARGET_ARCHITECTURE "sandy-bridge") - elseif(_cpu_model EQUAL 37) # Core i7/i5/i3 - set(TARGET_ARCHITECTURE "westmere") - elseif(_cpu_model EQUAL 31) # Core i7/i5 - set(TARGET_ARCHITECTURE "westmere") - elseif(_cpu_model EQUAL 30) # Core i7/i5 - set(TARGET_ARCHITECTURE "westmere") - elseif(_cpu_model EQUAL 29) - set(TARGET_ARCHITECTURE "penryn") - elseif(_cpu_model EQUAL 28) - set(TARGET_ARCHITECTURE "atom") - elseif(_cpu_model EQUAL 26) - set(TARGET_ARCHITECTURE "nehalem") - elseif(_cpu_model EQUAL 23) - set(TARGET_ARCHITECTURE "penryn") - elseif(_cpu_model EQUAL 15) - set(TARGET_ARCHITECTURE "merom") - elseif(_cpu_model EQUAL 14) - set(TARGET_ARCHITECTURE "core") - elseif(_cpu_model LESS 14) - message(WARNING "Your CPU (family ${_cpu_family}, model ${_cpu_model}) is not known. Auto-detection of optimization flags failed and will use the generic CPU settings with SSE2.") - set(TARGET_ARCHITECTURE "generic") - else() - message(WARNING "Your CPU (family ${_cpu_family}, model ${_cpu_model}) is not known. Auto-detection of optimization flags failed and will use the 65nm Core 2 CPU settings.") - set(TARGET_ARCHITECTURE "merom") - endif() - elseif(_cpu_family EQUAL 7) # Itanium (not supported) - message(WARNING "Your CPU (Itanium: family ${_cpu_family}, model ${_cpu_model}) is not supported by OptimizeForArchitecture.cmake.") - elseif(_cpu_family EQUAL 15) # NetBurst - list(APPEND _available_vector_units_list "sse" "sse2") - if(_cpu_model GREATER 2) # Not sure whether this must be 3 or even 4 instead - list(APPEND _available_vector_units_list "sse" "sse2" "sse3") - endif(_cpu_model GREATER 2) - endif(_cpu_family EQUAL 6) - elseif(_vendor_id STREQUAL "AuthenticAMD") - if(_cpu_family EQUAL 21) # 15h - set(TARGET_ARCHITECTURE "bulldozer") - elseif(_cpu_family EQUAL 20) # 14h - elseif(_cpu_family EQUAL 18) # 12h - elseif(_cpu_family EQUAL 16) # 10h - set(TARGET_ARCHITECTURE "barcelona") - elseif(_cpu_family EQUAL 15) - set(TARGET_ARCHITECTURE "k8") - if(_cpu_model GREATER 64) # I don't know the right number to put here. This is just a guess from the hardware I have access to - set(TARGET_ARCHITECTURE "k8-sse3") - endif(_cpu_model GREATER 64) - endif() - endif(_vendor_id STREQUAL "GenuineIntel") - message(STATUS "Detected CPU: ${TARGET_ARCHITECTURE}") - endif(TARGET_ARCHITECTURE STREQUAL "auto") - - if(TARGET_ARCHITECTURE STREQUAL "core") - list(APPEND _march_flag_list "core2") - list(APPEND _available_vector_units_list "sse" "sse2" "sse3") - elseif(TARGET_ARCHITECTURE STREQUAL "merom") - list(APPEND _march_flag_list "merom") - list(APPEND _march_flag_list "core2") - list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3") - elseif(TARGET_ARCHITECTURE STREQUAL "penryn") - list(APPEND _march_flag_list "penryn") - list(APPEND _march_flag_list "core2") - list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3") - message(STATUS "Sadly the Penryn architecture exists in variants with SSE4.1 and without SSE4.1.") - if(_cpu_flags MATCHES "sse4_1") - message(STATUS "SSE4.1: enabled (auto-detected from this computer's CPU flags)") - list(APPEND _available_vector_units_list "sse4.1") - else() - message(STATUS "SSE4.1: disabled (auto-detected from this computer's CPU flags)") - endif() - elseif(TARGET_ARCHITECTURE STREQUAL "nehalem") - list(APPEND _march_flag_list "nehalem") - list(APPEND _march_flag_list "corei7") - list(APPEND _march_flag_list "core2") - list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4.1" "sse4.2") - elseif(TARGET_ARCHITECTURE STREQUAL "westmere") - list(APPEND _march_flag_list "westmere") - list(APPEND _march_flag_list "corei7") - list(APPEND _march_flag_list "core2") - list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4.1" "sse4.2") - elseif(TARGET_ARCHITECTURE STREQUAL "sandy-bridge") - list(APPEND _march_flag_list "sandybridge") - list(APPEND _march_flag_list "corei7-avx") - list(APPEND _march_flag_list "core2") - list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4.1" "sse4.2" "avx") - elseif(TARGET_ARCHITECTURE STREQUAL "atom") - list(APPEND _march_flag_list "atom") - list(APPEND _march_flag_list "core2") - list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3") - elseif(TARGET_ARCHITECTURE STREQUAL "k8") - list(APPEND _march_flag_list "k8") - list(APPEND _available_vector_units_list "sse" "sse2") - elseif(TARGET_ARCHITECTURE STREQUAL "k8-sse3") - list(APPEND _march_flag_list "k8-sse3") - list(APPEND _march_flag_list "k8") - list(APPEND _available_vector_units_list "sse" "sse2" "sse3") - elseif(TARGET_ARCHITECTURE STREQUAL "interlagos") - list(APPEND _march_flag_list "bulldozer") - list(APPEND _march_flag_list "barcelona") - list(APPEND _march_flag_list "core2") - list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4a" "sse4.1" "sse4.2" "avx" "xop" "fma4") - elseif(TARGET_ARCHITECTURE STREQUAL "bulldozer") - list(APPEND _march_flag_list "bulldozer") - list(APPEND _march_flag_list "barcelona") - list(APPEND _march_flag_list "core2") - list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4a" "sse4.1" "sse4.2" "avx" "xop" "fma4") - elseif(TARGET_ARCHITECTURE STREQUAL "barcelona") - list(APPEND _march_flag_list "barcelona") - list(APPEND _march_flag_list "core2") - list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "sse4a") - elseif(TARGET_ARCHITECTURE STREQUAL "istanbul") - list(APPEND _march_flag_list "barcelona") - list(APPEND _march_flag_list "core2") - list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "sse4a") - elseif(TARGET_ARCHITECTURE STREQUAL "magny-cours") - list(APPEND _march_flag_list "barcelona") - list(APPEND _march_flag_list "core2") - list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "sse4a") - elseif(TARGET_ARCHITECTURE STREQUAL "generic") - list(APPEND _march_flag_list "generic") - else(TARGET_ARCHITECTURE STREQUAL "core") - message(FATAL_ERROR "Unknown target architecture: \"${TARGET_ARCHITECTURE}\". Please set TARGET_ARCHITECTURE to a supported value.") - endif(TARGET_ARCHITECTURE STREQUAL "core") - - set(_disable_vector_unit_list) - set(_enable_vector_unit_list) - _my_find(_available_vector_units_list "sse2" SSE2_FOUND) - _my_find(_available_vector_units_list "sse3" SSE3_FOUND) - _my_find(_available_vector_units_list "ssse3" SSSE3_FOUND) - _my_find(_available_vector_units_list "sse4.1" SSE4_1_FOUND) - _my_find(_available_vector_units_list "sse4.2" SSE4_2_FOUND) - _my_find(_available_vector_units_list "sse4a" SSE4a_FOUND) - _my_find(_available_vector_units_list "avx" AVX_FOUND) - _my_find(_available_vector_units_list "xop" XOP_FOUND) - _my_find(_available_vector_units_list "fma4" FMA4_FOUND) - set(USE_SSE2 ${SSE2_FOUND} CACHE BOOL "Use SSE2. If SSE2 instructions are not enabled the SSE implementation will be disabled." ${_force}) - set(USE_SSE3 ${SSE3_FOUND} CACHE BOOL "Use SSE3. If SSE3 instructions are not enabled they will be emulated." ${_force}) - set(USE_SSSE3 ${SSSE3_FOUND} CACHE BOOL "Use SSSE3. If SSSE3 instructions are not enabled they will be emulated." ${_force}) - set(USE_SSE4_1 ${SSE4_1_FOUND} CACHE BOOL "Use SSE4.1. If SSE4.1 instructions are not enabled they will be emulated." ${_force}) - set(USE_SSE4_2 ${SSE4_2_FOUND} CACHE BOOL "Use SSE4.2. If SSE4.2 instructions are not enabled they will be emulated." ${_force}) - set(USE_SSE4a ${SSE4a_FOUND} CACHE BOOL "Use SSE4a. If SSE4a instructions are not enabled they will be emulated." ${_force}) - set(USE_AVX ${AVX_FOUND} CACHE BOOL "Use AVX. This will double some of the vector sizes relative to SSE." ${_force}) - set(USE_XOP ${XOP_FOUND} CACHE BOOL "Use XOP." ${_force}) - set(USE_FMA4 ${FMA4_FOUND} CACHE BOOL "Use FMA4." ${_force}) - mark_as_advanced(USE_SSE2 USE_SSE3 USE_SSSE3 USE_SSE4_1 USE_SSE4_2 USE_SSE4a USE_AVX) - if(USE_SSE2) - list(APPEND _enable_vector_unit_list "sse2") - else(USE_SSE2) - list(APPEND _disable_vector_unit_list "sse2") - endif(USE_SSE2) - if(USE_SSE3) - list(APPEND _enable_vector_unit_list "sse3") - else(USE_SSE3) - list(APPEND _disable_vector_unit_list "sse3") - endif(USE_SSE3) - if(USE_SSSE3) - list(APPEND _enable_vector_unit_list "ssse3") - else(USE_SSSE3) - list(APPEND _disable_vector_unit_list "ssse3") - endif(USE_SSSE3) - if(USE_SSE4_1) - list(APPEND _enable_vector_unit_list "sse4.1") - else(USE_SSE4_1) - list(APPEND _disable_vector_unit_list "sse4.1") - endif(USE_SSE4_1) - if(USE_SSE4_2) - list(APPEND _enable_vector_unit_list "sse4.2") - else(USE_SSE4_2) - list(APPEND _disable_vector_unit_list "sse4.2") - endif(USE_SSE4_2) - if(USE_SSE4a) - list(APPEND _enable_vector_unit_list "sse4a") - else(USE_SSE4a) - list(APPEND _disable_vector_unit_list "sse4a") - endif(USE_SSE4a) - if(USE_AVX) - list(APPEND _enable_vector_unit_list "avx") - # we want SSE intrinsics to result in instructions using the VEX prefix. - # Otherwise integer ops (which require the older SSE intrinsics) would - # always have a large penalty. - list(APPEND _enable_vector_unit_list "sse2avx") - else(USE_AVX) - list(APPEND _disable_vector_unit_list "avx") - endif(USE_AVX) - if(USE_XOP) - list(APPEND _enable_vector_unit_list "xop") - else() - list(APPEND _disable_vector_unit_list "xop") - endif() - if(USE_FMA4) - list(APPEND _enable_vector_unit_list "fma4") - else() - list(APPEND _disable_vector_unit_list "fma4") - endif() - if(CMAKE_C_COMPILER MATCHES "cl(.exe)?$") # MSVC - # MSVC on 32 bit can select only /arch:SSE2 - # MSVC on 64 bit cannot select anything - if(NOT CMAKE_CL_64) - _my_find(_enable_vector_unit_list "sse2" _found) - if(_found) - AddCompilerFlag("/arch:SSE2") - endif() - endif(NOT CMAKE_CL_64) - foreach(_flag ${_enable_vector_unit_list}) - string(TOUPPER "${_flag}" _flag) - string(REPLACE "." "_" _flag "__${_flag}__") - add_definitions("-D${_flag}") - endforeach(_flag) - elseif(CMAKE_CXX_COMPILER MATCHES "/(icpc|icc)$") # ICC - _my_find(_available_vector_units_list "avx" _found) - if(_found) - AddCompilerFlag("-xAVX") - else(_found) - _my_find(_available_vector_units_list "sse4.2" _found) - if(_found) - AddCompilerFlag("-xSSE4.2") - else(_found) - _my_find(_available_vector_units_list "sse4.1" _found) - if(_found) - AddCompilerFlag("-xSSE4.1") - else(_found) - _my_find(_available_vector_units_list "ssse3" _found) - if(_found) - AddCompilerFlag("-xSSSE3") - else(_found) - _my_find(_available_vector_units_list "sse3" _found) - if(_found) - # If the target host is an AMD machine then we still want to use -xSSE2 because the binary would refuse to run at all otherwise - _my_find(_march_flag_list "barcelona" _found) - if(NOT _found) - _my_find(_march_flag_list "k8-sse3" _found) - endif(NOT _found) - if(_found) - AddCompilerFlag("-xSSE2") - else(_found) - AddCompilerFlag("-xSSE3") - endif(_found) - else(_found) - _my_find(_available_vector_units_list "sse2" _found) - if(_found) - AddCompilerFlag("-xSSE2") - endif(_found) - endif(_found) - endif(_found) - endif(_found) - endif(_found) - endif(_found) - else(CMAKE_C_COMPILER MATCHES "cl(.exe)?$") - foreach(_flag ${_march_flag_list}) - AddCompilerFlag("-march=${_flag}" _good) - if(_good) - break() - endif(_good) - endforeach(_flag) - foreach(_flag ${_enable_vector_unit_list}) - AddCompilerFlag("-m${_flag}") - endforeach(_flag) - foreach(_flag ${_disable_vector_unit_list}) - AddCompilerFlag("-mno-${_flag}") - endforeach(_flag) - # Not really target architecture specific, but GCC 4.5.[01] fail at inlining some functions, - # creating functions with a single instructions, thus a large overhead. This is a good - # (because central) place to fix the problem - if(CMAKE_COMPILER_IS_GNUCXX) - exec_program(${CMAKE_C_COMPILER} ARGS -dumpversion OUTPUT_VARIABLE _gcc_version) - macro_ensure_version("4.5.0" "${_gcc_version}" GCC_4_5_0) - if(GCC_4_5_0) - macro_ensure_version("4.5.2" "${_gcc_version}" GCC_4_5_2) - if(NOT GCC_4_5_2) - AddCompilerFlag("--param early-inlining-insns=12") - endif(NOT GCC_4_5_2) - endif(GCC_4_5_0) - endif(CMAKE_COMPILER_IS_GNUCXX) - endif(CMAKE_C_COMPILER MATCHES "cl(.exe)?$") -endmacro(OptimizeForArchitecture) diff --git a/Kommon/cmake/ResolveCompilerPaths.cmake b/Kommon/cmake/ResolveCompilerPaths.cmake deleted file mode 100644 index 98e8d24b3..000000000 --- a/Kommon/cmake/ResolveCompilerPaths.cmake +++ /dev/null @@ -1,93 +0,0 @@ -# ResolveCompilerPaths - this module defines two macros -# -# RESOLVE_LIBRARIES (XXX_LIBRARIES LINK_LINE) -# This macro is intended to be used by FindXXX.cmake modules. -# It parses a compiler link line and resolves all libraries -# (-lfoo) using the library path contexts (-L/path) in scope. -# The result in XXX_LIBRARIES is the list of fully resolved libs. -# Example: -# -# RESOLVE_LIBRARIES (FOO_LIBRARIES "-L/A -la -L/B -lb -lc -ld") -# -# will be resolved to -# -# FOO_LIBRARIES:STRING="/A/liba.so;/B/libb.so;/A/libc.so;/usr/lib/libd.so" -# -# if the filesystem looks like -# -# /A: liba.so libc.so -# /B: liba.so libb.so -# /usr/lib: liba.so libb.so libc.so libd.so -# -# and /usr/lib is a system directory. -# -# Note: If RESOLVE_LIBRARIES() resolves a link line differently from -# the native linker, there is a bug in this macro (please report it). -# -# RESOLVE_INCLUDES (XXX_INCLUDES INCLUDE_LINE) -# This macro is intended to be used by FindXXX.cmake modules. -# It parses a compile line and resolves all includes -# (-I/path/to/include) to a list of directories. Other flags are ignored. -# Example: -# -# RESOLVE_INCLUDES (FOO_INCLUDES "-I/A -DBAR='\"irrelevant -I/string here\"' -I/B") -# -# will be resolved to -# -# FOO_INCLUDES:STRING="/A;/B" -# -# assuming both directories exist. -# Note: as currently implemented, the -I/string will be picked up mistakenly (cry, cry) - -macro (RESOLVE_LIBRARIES LIBS LINK_LINE) - string (REGEX MATCHALL "((-L|-l|-Wl)([^\" ]+|\"[^\"]+\")|/[^\" ]+(a|so|dll))" _all_tokens "${LINK_LINE}") - set (_libs_found) - set (_directory_list) - foreach (token ${_all_tokens}) - if (token MATCHES "-L([^\" ]+|\"[^\"]+\")") - # If it's a library path, add it to the list - string (REGEX REPLACE "^-L" "" token ${token}) - string (REGEX REPLACE "//" "/" token ${token}) - list (APPEND _directory_list ${token}) - elseif (token MATCHES "^(-l([^\" ]+|\"[^\"]+\")|/[^\" ]+(a|so|dll))") - # It's a library, resolve the path by looking in the list and then (by default) in system directories - string (REGEX REPLACE "^-l" "" token ${token}) - set (_root) - if (token MATCHES "^/") # We have an absolute path, add root to the search path - set (_root "/") - endif (token MATCHES "^/") - set (_lib "NOTFOUND" CACHE FILEPATH "Cleared" FORCE) - find_library (_lib ${token} HINTS ${_directory_list} ${_root}) - if (_lib) - string (REPLACE "//" "/" _lib ${_lib}) - list (APPEND _libs_found ${_lib}) - else (_lib) - message (STATUS "Unable to find library ${token}") - endif (_lib) - endif (token MATCHES "-L([^\" ]+|\"[^\"]+\")") - endforeach (token) - set (_lib "NOTFOUND" CACHE INTERNAL "Scratch variable" FORCE) - # only the LAST occurence of each library is required since there should be no circular dependencies - if (_libs_found) - list (REVERSE _libs_found) - list (REMOVE_DUPLICATES _libs_found) - list (REVERSE _libs_found) - endif (_libs_found) - set (${LIBS} "${_libs_found}") -endmacro (RESOLVE_LIBRARIES) - -macro (RESOLVE_INCLUDES INCS COMPILE_LINE) - string (REGEX MATCHALL "-I([^\" ]+|\"[^\"]+\")" _all_tokens "${COMPILE_LINE}") - set (_incs_found) - foreach (token ${_all_tokens}) - string (REGEX REPLACE "^-I" "" token ${token}) - string (REGEX REPLACE "//" "/" token ${token}) - if (EXISTS ${token}) - list (APPEND _incs_found ${token}) - else (EXISTS ${token}) - message (STATUS "Include directory ${token} does not exist") - endif (EXISTS ${token}) - endforeach (token) - list (REMOVE_DUPLICATES _incs_found) - set (${INCS} "${_incs_found}") -endmacro (RESOLVE_INCLUDES) \ No newline at end of file diff --git a/Kommon/cmake/SelectLibraryConfigurations.cmake b/Kommon/cmake/SelectLibraryConfigurations.cmake new file mode 100644 index 000000000..4c0e9a8c0 --- /dev/null +++ b/Kommon/cmake/SelectLibraryConfigurations.cmake @@ -0,0 +1,80 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +SelectLibraryConfigurations +--------------------------- + +.. code-block:: cmake + + select_library_configurations(basename) + +This macro takes a library base name as an argument, and will choose +good values for the variables + +:: + + basename_LIBRARY + basename_LIBRARIES + basename_LIBRARY_DEBUG + basename_LIBRARY_RELEASE + +depending on what has been found and set. + +If only ``basename_LIBRARY_RELEASE`` is defined, ``basename_LIBRARY`` will +be set to the release value, and ``basename_LIBRARY_DEBUG`` will be set +to ``basename_LIBRARY_DEBUG-NOTFOUND``. If only ``basename_LIBRARY_DEBUG`` +is defined, then ``basename_LIBRARY`` will take the debug value, and +``basename_LIBRARY_RELEASE`` will be set to ``basename_LIBRARY_RELEASE-NOTFOUND``. + +If the generator supports configuration types, then ``basename_LIBRARY`` +and ``basename_LIBRARIES`` will be set with debug and optimized flags +specifying the library to be used for the given configuration. If no +build type has been set or the generator in use does not support +configuration types, then ``basename_LIBRARY`` and ``basename_LIBRARIES`` +will take only the release value, or the debug value if the release one +is not set. +#]=======================================================================] + +# This macro was adapted from the FindQt4 CMake module and is maintained by Will +# Dicharry . + +macro(select_library_configurations basename) + if(NOT ${basename}_LIBRARY_RELEASE) + set(${basename}_LIBRARY_RELEASE "${basename}_LIBRARY_RELEASE-NOTFOUND" CACHE FILEPATH "Path to a library.") + endif() + if(NOT ${basename}_LIBRARY_DEBUG) + set(${basename}_LIBRARY_DEBUG "${basename}_LIBRARY_DEBUG-NOTFOUND" CACHE FILEPATH "Path to a library.") + endif() + + get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if( ${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE AND + NOT ${basename}_LIBRARY_DEBUG STREQUAL ${basename}_LIBRARY_RELEASE AND + ( _isMultiConfig OR CMAKE_BUILD_TYPE ) ) + # if the generator is multi-config or if CMAKE_BUILD_TYPE is set for + # single-config generators, set optimized and debug libraries + set( ${basename}_LIBRARY "" ) + foreach( _libname IN LISTS ${basename}_LIBRARY_RELEASE ) + list( APPEND ${basename}_LIBRARY optimized "${_libname}" ) + endforeach() + foreach( _libname IN LISTS ${basename}_LIBRARY_DEBUG ) + list( APPEND ${basename}_LIBRARY debug "${_libname}" ) + endforeach() + elseif( ${basename}_LIBRARY_RELEASE ) + set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} ) + elseif( ${basename}_LIBRARY_DEBUG ) + set( ${basename}_LIBRARY ${${basename}_LIBRARY_DEBUG} ) + else() + set( ${basename}_LIBRARY "${basename}_LIBRARY-NOTFOUND") + endif() + + set( ${basename}_LIBRARIES "${${basename}_LIBRARY}" ) + + if( ${basename}_LIBRARY ) + set( ${basename}_FOUND TRUE ) + endif() + + mark_as_advanced( ${basename}_LIBRARY_RELEASE + ${basename}_LIBRARY_DEBUG + ) +endmacro() diff --git a/Kommon/cmake/update.sh b/Kommon/cmake/update.sh index 14908c2ae..59aebca8b 100755 --- a/Kommon/cmake/update.sh +++ b/Kommon/cmake/update.sh @@ -1,9 +1,15 @@ #!/bin/sh -CMAKE_VERSION="v3.13.0" +# A simple script to pull files from the CMake repository. + +CMAKE_VERSION="v3.14.0" GITHUB_URL="https://raw.githubusercontent.com/Kitware/CMake" -for name in *.cmake; do - cp -af "${name}" "${name}.update.bak" - wget -q "${GITHUB_URL}/${CMAKE_VERSION}/Modules/${name}" -O "${name}.update" && mv "${name}.update" "${name}" && echo "Updated ${name}" +for name in $(find ! -name '*.bak' -a ! -name '*.in' -type f) ; do + cp -af "${name}" "${name}.bak" + wget -q "${GITHUB_URL}/${CMAKE_VERSION}/Modules/${name}" -O "${name}.update" && \ + mv "${name}.update" "${name}" && \ + echo "Updated ${name}" && \ + git add ${name} + rm -f "${name}.update" done diff --git a/README.md b/README.md index 03705968a..8bd3d8954 100644 --- a/README.md +++ b/README.md @@ -18,16 +18,16 @@ NOTE: Kasper requires Linux/MacOS. Windows+cygwin should work too, but has not b Some dependencies are only required if certain module are compiled in. Dependencies: -* CMake (https://www.cmake.org) version 3.13 or higher +* CMake (https://www.cmake.org) version 3.14 or higher * G++ (https://gcc.gnu.org) version 6.1 or higher (if compiling with GCC) * Clang++ (https://clang.llvm.org) version 3.4 or higher (if compiling with clang) +* Boost (https://www.boost.org) version 1.65 or higher * GSL (https://www.gnu.org/software/gsl) -* ROOT (https://www.cern.ch/root) version 6.0 or higher +* ROOT (https://www.cern.ch/root) version 6.16 or higher + --enable-minuit2 (if you want to use KaFit) + --enable-fftw3 (if you want to use KEMField) Optional Dependencies: -* Boost (https://www.boost.org) version 1.61 or higher * FFTW (https://fftw.org) version 3.3.4 or higher * HDF5 (https://support.hdfgroup.org/HDF5/) * LibXml2 (https://www.xmlsoft.org) diff --git a/Scripts/module-deps-graph.sh b/Scripts/module-deps-graph.sh index da46dcb3b..172396ea2 100755 --- a/Scripts/module-deps-graph.sh +++ b/Scripts/module-deps-graph.sh @@ -10,100 +10,21 @@ BASE=${1:-${PWD}} -if [ ! -f "${BASE}/CMakeLists.txt" -o ! -d "${PWD}/.git" ]; then - printf "Script needs to be run in a source directory! Exiting...\n" +if [ ! -f "${BASE}/../CMakeLists.txt" -o ! -d "${PWD}/../.git" ]; then + printf "Script needs to be run in a build directory! Exiting...\n" exit 1 fi -NAME="${BASE}/module-deps-graph" +NAME="${BASE}/../module-deps-graph" -cmake_files=$(git ls-tree --full-tree -r --name-only HEAD -- "${BASE}" \ - | egrep 'CMakeLists\.txt$' \ - | egrep -v '([Ee]xamples)\/' \ - ) +cmake --graphviz="${NAME}.dot" .. || exit $? -# List of module names, based on CMakeLists.txt project definitions. -# This trick makes all actual CMake projects to be drawn as boxes. -# Unreferenced projects are hidden from the graph. -project_names=$( - echo "${cmake_files}" \ - | xargs grep -H 'project' \ - | sed -nr \ - -e 's/^([a-zA-Z0-9_\/]+)\/CMakeLists\.txt:\s*project\s*\(\s*([a-zA-Z_-]+)\s*.*\)/"\2"/p' \ - | sort | uniq \ - | sed 's/\//\/\\n/g' \ - ) - -# List of module names, based on CMakeLists.txt location. -# If the module name is a CMake project, it will be drawn as a box (see above). -module_names=$( - echo "${cmake_files}" \ - | xargs grep -H 'kasper_find_module' \ - | sed -nr \ - -e 's/^([a-zA-Z0-9_\/]+)\/CMakeLists\.txt:\s*kasper_find_module\s*\(\s*([a-zA-Z_-]+)\s*\)/"\1"/p' \ - | sort | uniq \ - | sed 's/\//\/\\n/g' \ - ) - -# List of module targets, based on kasper_find_module() expressions. -# If the module target is a CMake project, it will be drawn as a box (see above). -# All module targets are drawn in red color. -module_targets=$( - echo "${cmake_files}" \ - | xargs grep -H 'kasper_find_module' \ - | sed -nr \ - -e 's/^([a-zA-Z0-9_\/]+)\/CMakeLists\.txt:\s*kasper_find_module\s*\(\s*([a-zA-Z_-]+)\s*\)/"\2"/p' \ - | sort | uniq \ - | sed 's/\//\/\\n/g' \ - ) - -# Graph of CMake files to Kasper modules; combines module names and module targets. -module_deps=$( \ - echo "${cmake_files}" \ - | xargs grep -H 'kasper_find_module' \ - | sed -nr \ - -e 's/^([a-zA-Z0-9_\/]+)\/CMakeLists\.txt:\s*kasper_find_module\s*\(\s*([a-zA-Z_-]+)\s*\)/"\1"->"\2"/p' \ - | sort | uniq \ - | sed 's/\//\/\\n/g' \ - ) - -if [ -z "${module_deps}" ]; then - echo "Found NO dependencies for ${BASE}" - exit -1 -fi - -echo > $NAME.dot -echo "digraph \"${NAME}\" {" >> $NAME.dot -echo " splines=true; overlap=false; rankdir=LR; ordering=out;" >> $NAME.dot -echo " node[shape=box];" >> $NAME.dot -echo "# package_names" >> $NAME.dot -for node in ${project_names}; do - echo " ${node} [style=invis,shape=box];" >> $NAME.dot -done -echo "# module_names" >> $NAME.dot -for node in ${module_names}; do - echo " ${node} [style=filled,color=lightgrey];" >> $NAME.dot -done -for node in ${project_names}; do - echo " ${node} [color=lightgreen];" >> $NAME.dot -done -echo "# module_targets" >> $NAME.dot -echo "subgraph cluster_targets {" >> $NAME.dot -echo " style=filled; color=none;" >> $NAME.dot -for node in ${module_targets}; do - echo " ${node} [style=filled,color=lightblue];" >> $NAME.dot -done -echo "}" >> $NAME.dot -echo "# module_deps" >> $NAME.dot -for edge in ${module_deps}; do - echo " ${edge} [style=solid];" >> $NAME.dot -done -echo "}" >> $NAME.dot +sed -i 's/shape = egg/shape = egg,style=filled,color=lightpink/g' $NAME.dot +sed -i 's/shape = doubleoctagon/shape = octagon,style=filled,color=lightgreen/g' $NAME.dot +sed -i 's/shape = pentagon/shape = pentagon,style=filled,color=lightgrey/g' $NAME.dot +sed -i 's/shape = hexagon/shape = hexagon,style=filled,color=lightblue/g' $NAME.dot dot -Tpng -o$NAME.png $NAME.dot echo "Dependency scan of ${BASE} completed:" -echo " $(echo "${project_names}" | wc -l) CMake projects" -echo " $(echo "${module_targets}" | wc -l) Kasper modules" -echo " $(echo "${module_deps}" | wc -l) internal dependencies" echo "Output created in: ${NAME}.{dot,png}" diff --git a/UnitTest/CMakeLists.txt b/UnitTest/CMakeLists.txt index dabc562af..fabcbae04 100644 --- a/UnitTest/CMakeLists.txt +++ b/UnitTest/CMakeLists.txt @@ -3,9 +3,10 @@ cmake_minimum_required( VERSION ${CMAKE_MINIMUM_VERSION} ) # UnitTest version set( MODULE_VERSION_MAJOR 0 ) set( MODULE_VERSION_MINOR 2 ) -set( MODULE_VERSION_PATCH 5 ) +set( MODULE_VERSION_PATCH 6 ) set( MODULE_VERSION "${MODULE_VERSION_MAJOR}.${MODULE_VERSION_MINOR}.${MODULE_VERSION_PATCH}" ) +#project( UnitTest VERSION ${MODULE_VERSION} ) project( UnitTest ) include( KasperDefaults ) @@ -22,20 +23,21 @@ include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) # the gtest and gtest_main targets. add_subdirectory(GoogleTest) -if (CMAKE_VERSION VERSION_LESS 2.8.11) - include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../GoogleTest/include") -endif() - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Include - ${CMAKE_CURRENT_SOURCE_DIR}/MockUps/Include -) - - ## MockUps sub-modules add_subdirectory( MockUps ) +add_library( UnitTestBase INTERFACE ) +target_include_directories( UnitTestBase INTERFACE + $ + $ + $ +) +target_link_libraries( UnitTestBase INTERFACE gtest ) +kasper_install_libraries( UnitTestBase ) + +set(GTEST_MAIN_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/GoogleTest//src/gtest_main.cc) + ## Kasper sub-modules if( BUILD_KOMMON ) diff --git a/UnitTest/KEMField/CMakeLists.txt b/UnitTest/KEMField/CMakeLists.txt index b804c936e..cb09eb95d 100644 --- a/UnitTest/KEMField/CMakeLists.txt +++ b/UnitTest/KEMField/CMakeLists.txt @@ -1,41 +1,8 @@ # CMakeLists for KEMField/UnitTest # Author: J. Behrens adapted for KEMField W. Gosda -kasper_find_module( KEMField ) - -if( KEMField_USE_MPI ) - #find_package(MPI) - if (MPI_CXX_FOUND) - if (MPI_CXX_COMPILER) # MPICH2 style - set (CMAKE_C_COMPILER ${MPI_CXX_COMPILER}) - set (CMAKE_CXX_COMPILER ${MPI_CXX_COMPILER}) - else (MPI_CXX_COMPILER) # OpenMPI style - set (CMAKE_C_COMPILER ${MPI_C_COMPILER}) - set (CMAKE_CXX_COMPILER ${MPI_CXX_COMPILER}) - endif (MPI_CXX_COMPILER) - else (MPI_CXX_FOUND) - message(WARNING "Warning: MPI not found on your system, using default compiler" ) - set (CMAKE_C_COMPILER mpicc) - set (CMAKE_CXX_COMPILER mpicxx) - endif (MPI_CXX_FOUND) - add_cflag (KEMFIELD_USE_MPI) - -endif( KEMField_USE_MPI ) - enable_testing() -set( gtest_SOURCE_DIR - ${CMAKE_CURRENT_SOURCE_DIR}/../GoogleTest -) - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${CMAKE_CURRENT_SOURCE_DIR}/Fields/include - ${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/Solvers/include - ${gtest_SOURCE_DIR}/include - ${KEMField_INCLUDE_DIRS} -) - set (UNIT_TESTS_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMFieldTest.hh #${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebra/Solvers/include/KrylovFactoryFixture.hh @@ -71,45 +38,46 @@ endif() # endif(KEMField_USE_KOMMON_BINDINGS) - # Build (static) library for KEMField's unit tests +add_library(KEMFieldUnitTests SHARED ${UNIT_TESTS_SOURCEFILES} ${UNIT_TESTS_HEADERFILES}) +target_include_directories( KEMFieldUnitTests + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include) +target_link_libraries(KEMFieldUnitTests + PUBLIC + UnitTestBase + KGeoBagInterface + KEMCore + KEMLinearAlgebraCore + KEMBoundaryIntegralsCore + KEMElectrostaticBoundaryIntegrals + KEMFieldChargeDensitySolvers + KEMFieldsElectric + KEMFieldsMagnetic + KEMElectromagnets + KEMZHSolver +) + + if (KEMField_USE_OPENCL) find_package (OpenCL REQUIRED) - kasper_external_include_directories( ${OPENCL_INCLUDE_DIRS} ) - add_cflag (KEMFIELD_USE_OPENCL) - list (APPEND KEMFIELD_UNIT_TEST_LIBS - KEMOpenCLPlugin - ) + target_compile_definitions (KEMFieldUnitTests PUBLIC KEMFIELD_USE_OPENCL) + target_link_libraries (KEMFieldUnitTests PUBLIC KEMOpenCLPlugin) endif (KEMField_USE_OPENCL) if (KEMField_USE_PETSc) find_package (PETSc REQUIRED) - kasper_external_include_directories (${PETSC_INCLUDES}) - add_cflag (KEMFIELD_USE_PETSC) - list (APPEND KEMFIELD_UNIT_TEST_LIBS - KEMPETScPlugin - ) + target_compile_definitions (KEMFieldUnitTests PUBLIC KEMFIELD_USE_PETSC) + target_link_libraries (KEMFieldUnitTests PUBLIC KEMPETScPlugin) endif (KEMField_USE_PETSc) - -add_library(KEMFieldUnitTests SHARED ${UNIT_TESTS_SOURCEFILES} ${UNIT_TESTS_HEADERFILES}) -target_link_libraries(KEMFieldUnitTests - gtest - ${GSL_LIBRARIES} - ${FFTW_LIBRARIES} - ${Kommon_LIBRARIES} - ${Kommon_Vtk_LIBRARIES} - ${KEMField_LIBRARIES} - ${KEMFIELD_UNIT_TEST_LIBS} -) kasper_install_libraries(KEMFieldUnitTests) # Build executable for KEMField's unit tests -add_executable(UnitTestKEMField ${gtest_SOURCE_DIR}/src/gtest_main.cc) -target_link_libraries(UnitTestKEMField KEMFieldUnitTests gtest) +add_executable(UnitTestKEMField ${GTEST_MAIN_SOURCE}) +target_link_libraries(UnitTestKEMField KEMFieldUnitTests) kasper_install_executables(UnitTestKEMField) add_test (NAME UnitTestKEMField COMMAND UnitTestKEMField) diff --git a/UnitTest/KEMField/Plugins/Bindings/CMakeLists.txt b/UnitTest/KEMField/Plugins/Bindings/CMakeLists.txt index 29e844146..adc7513b4 100644 --- a/UnitTest/KEMField/Plugins/Bindings/CMakeLists.txt +++ b/UnitTest/KEMField/Plugins/Bindings/CMakeLists.txt @@ -3,15 +3,6 @@ enable_testing() -#set( gtest_SOURCE_DIR -# ${CMAKE_CURRENT_SOURCE_DIR}/../GoogleTest -#) - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${KEMField_INCLUDE_DIRS} -) - set (UNIT_TESTS_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/include/KSmartPointerReleaseTest.hh ${CMAKE_CURRENT_SOURCE_DIR}/include/KEMToolboxFixture.hh @@ -24,36 +15,33 @@ set (UNIT_TESTS_SOURCEFILES ${CMAKE_CURRENT_SOURCE_DIR}/src/KSmartPointerRelease.cc ) -set (UNIT_TESTS_LINK_LIBRARIES - gtest - ${Boost_LIBRARIES} - ${Kommon_LIBRARIES} - ${KEMField_LIBRARIES} -) - # options not accessible from here -#if(@PROJECT_NAME@_USE_VTK) +#if(KEMField_USE_VTK) set (UNIT_TESTS_SOURCEFILES ${UNIT_TESTS_SOURCEFILES} ${CMAKE_CURRENT_SOURCE_DIR}/src/KBoundaryField_Visitor.cc ) set (UNIT_TESTS_LINK_LIBRARIES ${UNIT_TESTS_LINK_LIBRARIES} KEMVTKPart2 ) -#endif() +#endif(KEMField_USE_VTK) # Build (static) library for KEMField's binding's unit tests add_library( KEMBindingsUnitTests SHARED ${UNIT_TESTS_SOURCEFILES} ${UNIT_TESTS_HEADERFILES} ) +target_include_directories( KEMBindingsUnitTests + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/include ) target_link_libraries (KEMBindingsUnitTests - ${UNIT_TESTS_LINK_LIBRARIES} + PUBLIC + UnitTestBase + KEMFieldBindings ) kasper_install_libraries (KEMBindingsUnitTests) # Build executable for KEMField's unit tests -add_executable (UnitTestKEMBindings ${gtest_SOURCE_DIR}/src/gtest_main.cc) -target_link_libraries (UnitTestKEMBindings gtest KEMBindingsUnitTests) +add_executable (UnitTestKEMBindings ${GTEST_MAIN_SOURCE}) +target_link_libraries (UnitTestKEMBindings KEMBindingsUnitTests) kasper_install_executables (UnitTestKEMBindings) add_test (NAME UnitTestKEMBindings COMMAND UnitTestKEMBindings) diff --git a/UnitTest/KEMField/Plugins/Bindings/src/KBoundaryField_Visitor.cc b/UnitTest/KEMField/Plugins/Bindings/src/KBoundaryField_Visitor.cc index 1e2b32f38..0b5c69c78 100644 --- a/UnitTest/KEMField/Plugins/Bindings/src/KBoundaryField_Visitor.cc +++ b/UnitTest/KEMField/Plugins/Bindings/src/KBoundaryField_Visitor.cc @@ -5,7 +5,7 @@ * Author: wolfgang */ -#include "../../../../../KEMField/Source/2.0/Plugins/VTKPart2/include/KVTKViewerAsBoundaryFieldVisitor.hh" +#include "KVTKViewerAsBoundaryFieldVisitor.hh" #include "KContainer.hh" #include "KEMFieldTest.hh" #include "KElectrostaticBoundaryField.hh" diff --git a/UnitTest/KGeoBag/CMakeLists.txt b/UnitTest/KGeoBag/CMakeLists.txt index dbcf5afb9..41160db77 100644 --- a/UnitTest/KGeoBag/CMakeLists.txt +++ b/UnitTest/KGeoBag/CMakeLists.txt @@ -1,22 +1,8 @@ # CMakeLists for KGeoBag/UnitTest # Author: J. Behrens -kasper_find_module( Kommon ) -kasper_find_module( KGeoBag ) - enable_testing() -set( gtest_SOURCE_DIR - ${CMAKE_CURRENT_SOURCE_DIR}/../GoogleTest -) - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Include - ${gtest_SOURCE_DIR}/include - ${Kommon_INCLUDE_DIRS} - ${KGeoBag_INCLUDE_DIRS} -) - set (UNIT_TESTS_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/Include/Shapes.h ) @@ -27,26 +13,25 @@ set (UNIT_TESTS_SOURCEFILES ${CMAKE_CURRENT_SOURCE_DIR}/Source/SpaceTree.cxx ) - ## Build (static) library for KGeoBag's unit tests add_library (KGeoBagUnitTests SHARED ${UNIT_TESTS_SOURCEFILES} ${UNIT_TESTS_HEADERFILES}) +target_include_directories( KGeoBagUnitTests + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Include ) target_link_libraries( KGeoBagUnitTests - gtest - ${Boost_LIBRARIES} - ${Kommon_LIBRARIES} - ${Kommon_Vtk_LIBRARIES} - ${KGeoBag_LIBRARIES} + PUBLIC + UnitTestBase + KGeoBagCore + KGeoBagShapes + KGeoBagMathSpaceTree ) kasper_install_libraries( KGeoBagUnitTests ) ## Build executable for KGeoBag's unit tests -add_executable (UnitTestKGeoBag ${gtest_SOURCE_DIR}/src/gtest_main.cc) +add_executable (UnitTestKGeoBag ${GTEST_MAIN_SOURCE}) target_link_libraries (UnitTestKGeoBag KGeoBagUnitTests) -# Important: we need this to avoid gcc throwing out the unit test symbols during linking -# set_target_properties (UnitTestKGeoBag PROPERTIES LINK_FLAGS "-Wl,--no-as-needed") kasper_install_executables (UnitTestKGeoBag) add_test (NAME UnitTestKGeoBag COMMAND UnitTestKGeoBag) diff --git a/UnitTest/Kasper/CMakeLists.txt b/UnitTest/Kasper/CMakeLists.txt index f6fb60ec9..882c57600 100644 --- a/UnitTest/Kasper/CMakeLists.txt +++ b/UnitTest/Kasper/CMakeLists.txt @@ -3,21 +3,10 @@ enable_testing() -set( gtest_SOURCE_DIR - ${CMAKE_CURRENT_SOURCE_DIR}/../GoogleTest -) - - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Include - ${gtest_SOURCE_DIR}/include -) - - ## Build executable for Kasper's global unit tests -add_executable (UnitTestKasper ${gtest_SOURCE_DIR}/src/gtest_main.cc) -target_link_libraries (UnitTestKasper ${UNIT_TEST_LIBS} gtest) +add_executable (UnitTestKasper ${GTEST_MAIN_SOURCE}) +target_link_libraries (UnitTestKasper ${UNIT_TEST_LIBS}) # Important: we need this to avoid gcc throwing out the unit test symbols during linking # set_target_properties(UnitTestKasper PROPERTIES LINK_FLAGS "-Wl,--no-as-needed" ) kasper_install_executables(UnitTestKasper) diff --git a/UnitTest/Kassiopeia/CMakeLists.txt b/UnitTest/Kassiopeia/CMakeLists.txt index 33fe4831d..88eef7b1d 100644 --- a/UnitTest/Kassiopeia/CMakeLists.txt +++ b/UnitTest/Kassiopeia/CMakeLists.txt @@ -1,21 +1,8 @@ # CMakeLists for Kassiopeia/UnitTest # Author: J. Behrens -kasper_find_module( Kassiopeia ) - enable_testing() -set( gtest_SOURCE_DIR - ${CMAKE_CURRENT_SOURCE_DIR}/../GoogleTest -) - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Include - ${gtest_SOURCE_DIR}/include - ${Kommon_INCLUDE_DIRS} - ${Kassiopeia_INCLUDE_DIRS} -) - set (UNIT_TESTS_HEADERFILES ${CMAKE_CURRENT_SOURCE_DIR}/Include/Generators.h ${CMAKE_CURRENT_SOURCE_DIR}/Include/Operators.h @@ -33,23 +20,22 @@ set (UNIT_TESTS_SOURCEFILES ## Build (static) library for Kassiopeia's unit tests add_library (KassiopeiaUnitTests SHARED ${UNIT_TESTS_SOURCEFILES} ${UNIT_TESTS_HEADERFILES}) +target_include_directories( KassiopeiaUnitTests + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Include) target_link_libraries (KassiopeiaUnitTests - gtest - ${ROOT_LIBRARIES} - ${Boost_LIBRARIES} - ${GSL_LIBRARIES} - ${KasperCommon_LIBRARIES} - ${Kassiopeia_LIBRARIES} + PUBLIC + UnitTestBase + KassiopeiaSimulation + KassiopeiaVisualization + ) kasper_install_libraries (KassiopeiaUnitTests) ## Build executable for Kassiopeia's unit tests -add_executable (UnitTestKassiopeia ${gtest_SOURCE_DIR}/src/gtest_main.cc) -target_link_libraries (UnitTestKassiopeia KassiopeiaUnitTests gtest) -# Important: we need this to avoid gcc throwing out the unit test symbols during linking -# set_target_properties (UnitTestKassiopeia PROPERTIES LINK_FLAGS "-Wl,--no-as-needed") +add_executable (UnitTestKassiopeia ${GTEST_MAIN_SOURCE}) +target_link_libraries (UnitTestKassiopeia KassiopeiaUnitTests) kasper_install_executables (UnitTestKassiopeia) add_test (NAME UnitTestKassiopeia COMMAND UnitTestKassiopeia) diff --git a/UnitTest/Kommon/CMakeLists.txt b/UnitTest/Kommon/CMakeLists.txt index a1aebeeb2..adf0fc88c 100644 --- a/UnitTest/Kommon/CMakeLists.txt +++ b/UnitTest/Kommon/CMakeLists.txt @@ -1,34 +1,8 @@ # CMakeLists for Kommon/UnitTest # Author: J. Behrens -kasper_find_module( Kommon ) - enable_testing() -set( gtest_SOURCE_DIR ../GoogleTest ) - -if (KASPER_USE_TBB) - find_package(TBB REQUIRED) - add_definitions(-DTBB) -endif () - -if (KASPER_USE_ROOT) - find_package(ROOT REQUIRED) - add_definitions(-DROOT) -endif () - -if (KASPER_USE_BOOST) - find_package(Boost REQUIRED) - add_definitions(-DBOOST) -endif() - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Include - ${gtest_SOURCE_DIR}/include - ${Kommon_INCLUDE_DIRS} - ${TBB_INCLUDE_DIR} -) - set (UNIT_TESTS_SOURCEFILES Math.cxx Integrator.cxx @@ -39,12 +13,17 @@ set (UNIT_TESTS_SOURCEFILES ## Build (static) library for Kommon's unit tests -add_library (KommonUnitTests SHARED ${UNIT_TESTS_SOURCEFILES} ${UNIT_TESTS_HEADERFILES}) +add_library (KommonUnitTests SHARED + ${UNIT_TESTS_SOURCEFILES} ${UNIT_TESTS_HEADERFILES}) +target_include_directories( KommonUnitTests + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + target_link_libraries (KommonUnitTests - gtest - ${Kommon_LIBRARIES} - ${TBB_LIBRARY} + PUBLIC + UnitTestBase + Kommon ) + kasper_install_libraries (KommonUnitTests) # xml configs used for unit tests @@ -64,10 +43,8 @@ kasper_install_config( ${TEST_CONFIG_FILES} ) ## Build executable for Kommon's unit tests -add_executable (UnitTestKommon ${gtest_SOURCE_DIR}/src/gtest_main.cc) -target_link_libraries (UnitTestKommon gtest KommonUnitTests) -# Important: we need this to avoid gcc throwing out the unit test symbols during linking -# set_target_properties (UnitTestKommon PROPERTIES LINK_FLAGS "-Wl,--no-as-needed") +add_executable (UnitTestKommon ${GTEST_MAIN_SOURCE}) +target_link_libraries (UnitTestKommon KommonUnitTests) kasper_install_executables (UnitTestKommon) add_test (NAME UnitTestKommon COMMAND UnitTestKommon) diff --git a/UnitTest/Kommon/Integrator.cxx b/UnitTest/Kommon/Integrator.cxx index ce4b765e6..0e61935dd 100644 --- a/UnitTest/Kommon/Integrator.cxx +++ b/UnitTest/Kommon/Integrator.cxx @@ -10,6 +10,8 @@ #include "KConst.h" #include "KMathIntegrator.h" +#include + #include using namespace katrin; @@ -17,14 +19,33 @@ using namespace std; TEST(KommonMath, Integrator) { - const double analytical = 0.5 * (erf(3.0 / sqrt(2)) - erf(-3.0 / sqrt(2))); + const double analytical = 0.5 * (erf(3.0 / sqrt(2)) - erf(-3.0 / sqrt(2))); // range [-3; 3] + const double analyticalOE = 0.5 * (1. - erf(-3.0 / sqrt(2))); // range [-3; inf) double numerical, precision; - KMathIntegrator integrator(1E-6, KEMathIntegrationMethod::Romberg); + KMathIntegrator integrator; auto integrand = [](double x) { return exp(-0.5 * x * x) / sqrt(2 * KConst::Pi()); }; + // Simpson (default) + integrator.SetMethod(KEMathIntegrationMethod::Simpson); + + precision = 1E-5; + integrator.SetPrecision(precision); + numerical = integrator.Integrate(integrand, -3.0, 3.0); + + EXPECT_EQ(65U, integrator.NumberOfSteps()); + ASSERT_NEAR(analytical, numerical, precision); + + numerical = integrator.Integrate(integrand, -3.0, 9999.); + + EXPECT_EQ(65537U, integrator.NumberOfSteps()); + ASSERT_NEAR(analyticalOE, numerical, precision); + + // Romberg + integrator.SetMethod(KEMathIntegrationMethod::Romberg); + precision = 1E-5; integrator.SetPrecision(precision); numerical = integrator.Integrate(integrand, -3.0, 3.0); @@ -39,18 +60,60 @@ TEST(KommonMath, Integrator) EXPECT_EQ(65U, integrator.NumberOfSteps()); ASSERT_NEAR(analytical, numerical, precision); + precision = 1E-6; + integrator.SetPrecision(precision); + numerical = integrator.Integrate(integrand, -3.0, 9999.); + + EXPECT_EQ(65537U, integrator.NumberOfSteps()); + ASSERT_NEAR(analyticalOE, numerical, precision); + + // Trapezoidal integrator.SetMethod(KEMathIntegrationMethod::Trapezoidal); + + precision = 1E-9; + integrator.SetPrecision(precision); numerical = integrator.Integrate(integrand, -3.0, 3.0); EXPECT_EQ(16385U, integrator.NumberOfSteps()); ASSERT_NEAR(analytical, numerical, precision); - integrator.SetMinSteps(2048); - EXPECT_EQ(2049U, integrator.GetMinSteps()); + precision = 1E-4; + integrator.SetPrecision(precision); + numerical = integrator.Integrate(integrand, -3.0, 9999.); + + EXPECT_EQ(65537U, integrator.NumberOfSteps()); + ASSERT_NEAR(analyticalOE, numerical, precision); + + integrator.SetMinSteps(32768); + EXPECT_EQ(32769U, integrator.GetMinSteps()); + + numerical = integrator.Integrate(integrand, -3.0, 3.0); + + EXPECT_EQ(32769U, integrator.NumberOfSteps()); + ASSERT_NEAR(analytical, numerical, precision); + +#ifdef KASPER_USE_GSL // need GSL support in Kommon + //QAGIU (always used, if upper boundary=INFINITY) + integrator.SetMethod(KEMathIntegrationMethod::QAGS); + + precision = 1E-6; + integrator.SetPrecision(precision); + numerical = integrator.Integrate(integrand, -3.0, INFINITY); // uses QAGIU + + EXPECT_EQ(5U, integrator.NumberOfSteps()); + ASSERT_NEAR(analyticalOE, numerical, precision); + + precision = 1E-9; + integrator.SetPrecision(precision); + numerical = integrator.Integrate(integrand, -3.0, 3.0); // uses QAGS + + EXPECT_EQ(2U, integrator.NumberOfSteps()); + ASSERT_NEAR(analytical, numerical, precision); +#endif } -#ifdef TBB +#ifdef KASPER_USE_TBB #include "KMathIntegratorThreaded.h" diff --git a/UnitTest/Kommon/TestXML.cxx b/UnitTest/Kommon/TestXML.cxx index d7621ae04..6f1809b53 100644 --- a/UnitTest/Kommon/TestXML.cxx +++ b/UnitTest/Kommon/TestXML.cxx @@ -237,7 +237,7 @@ TEST(XML, Variables) tTokenizer.ProcessFile(tFile); } -#ifdef ROOT +#ifdef KASPER_USE_ROOT #include "KFormulaProcessor.hh" diff --git a/UnitTest/MockUps/CMakeLists.txt b/UnitTest/MockUps/CMakeLists.txt index 8b866de7d..e69de29bb 100644 --- a/UnitTest/MockUps/CMakeLists.txt +++ b/UnitTest/MockUps/CMakeLists.txt @@ -1,8 +0,0 @@ -# CMakeLists for Kommon/UnitTest/Mockups -# Author: J. WGosda - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Include) - -set (UNIT_TEST_MOCKUPS_HEADERFILES -${CMAKE_CURRENT_SOURCE_DIR}/Include/SimpleClassHierachy.h -) diff --git a/UnitTest/ModuleConfig.cmake.in b/UnitTest/ModuleConfig.cmake.in deleted file mode 100644 index 968c7f35a..000000000 --- a/UnitTest/ModuleConfig.cmake.in +++ /dev/null @@ -1,23 +0,0 @@ -# $Id: ModuleConfig.cmake.in 12255 2012-03-16 09:26:20Z s_voec01 $ - -if(@PROJECT_NAME@_FOUND) - return() -endif() - -set(@PROJECT_NAME@_FOUND TRUE) - -# Update this section - -# The extra libraries one has to link against -set(@PROJECT_NAME@_DEPENDS ) -#list(REMOVE_DUPLICATES @PROJECT_NAME@_DEPENDS) -# End - -set(@PROJECT_NAME@_VERSION_MAJOR @MODULE_VERSION_MAJOR@) -set(@PROJECT_NAME@_VERSION_MINOR @MODULE_VERSION_MINOR@) -set(@PROJECT_NAME@_VERSION_PATCH @MODULE_VERSION_PATCH@) -set(@PROJECT_NAME@_VERSION @MODULE_VERSION@) - -set(@PROJECT_NAME@_INCLUDE_DIRS @MODULE_INCLUDE_DIRS@) -set(@PROJECT_NAME@_LIBRARIES @MODULE_TARGETS@) -mark_as_advanced(@PROJECT_NAME@_DIR) diff --git a/UnitTest/ModuleConfigInstalled.cmake.in b/UnitTest/ModuleConfigInstalled.cmake.in deleted file mode 100644 index 66649bc1d..000000000 --- a/UnitTest/ModuleConfigInstalled.cmake.in +++ /dev/null @@ -1,29 +0,0 @@ -# $Id: ModuleConfig.cmake.in 11925 2012-01-23 14:54:05Z s_voec01 $ - -if(@PROJECT_NAME@_FOUND) - return() -endif() - -set(@PROJECT_NAME@_FOUND TRUE) - -# Update this section - -set(@PROJECT_NAME@_DEPENDS) -#list(REMOVE_DUPLICATES @PROJECT_NAME@_DEPENDS) -# End - -set(@PROJECT_NAME@_VERSION_MAJOR @MODULE_VERSION_MAJOR@) -set(@PROJECT_NAME@_VERSION_MINOR @MODULE_VERSION_MINOR@) -set(@PROJECT_NAME@_VERSION_PATCH @MODULE_VERSION_PATCH@) -set(@PROJECT_NAME@_VERSION @MODULE_VERSION@) - -get_filename_component(MODULE_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) -if(EXISTS "${MODULE_CMAKE_DIR}/ModuleTargets.cmake") - include("${MODULE_CMAKE_DIR}/ModuleTargets.cmake") -elseif(NOT KASPER_TARGETS_INCLUDED) - include("${MODULE_CMAKE_DIR}/../Kasper/KasperTargets.cmake") - set(KASPER_TARGETS_INCLUDED TRUE) -endif() - -set(@PROJECT_NAME@_INCLUDE_DIRS @INSTALLED_INCLUDE_DIRS@) -set(@PROJECT_NAME@_LIBRARIES @MODULE_TARGETS@) diff --git a/UnitTest/UnitTestConfig.cmake.in b/UnitTest/UnitTestConfig.cmake.in new file mode 100644 index 000000000..ebaf9b526 --- /dev/null +++ b/UnitTest/UnitTestConfig.cmake.in @@ -0,0 +1,3 @@ +if(NOT TARGET @PROJECT_NAME@::@PROJECT_NAME@) + include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +endif() diff --git a/Kommon/ModuleConfigVersion.cmake.in b/UnitTest/UnitTestConfigVersion.cmake.in similarity index 96% rename from Kommon/ModuleConfigVersion.cmake.in rename to UnitTest/UnitTestConfigVersion.cmake.in index ad2e5531b..9805abae8 100644 --- a/Kommon/ModuleConfigVersion.cmake.in +++ b/UnitTest/UnitTestConfigVersion.cmake.in @@ -1,5 +1,3 @@ -# $Id$ - set(PACKAGE_VERSION "@MODULE_VERSION@") # Check whether the requested PACKAGE_FIND_VERSION is compatible @@ -10,4 +8,4 @@ else() if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") set(PACKAGE_VERSION_EXACT TRUE) endif() -endif() \ No newline at end of file +endif() diff --git a/module-deps-graph.png b/module-deps-graph.png index d64345e8e..a6cb1f2d7 100644 Binary files a/module-deps-graph.png and b/module-deps-graph.png differ diff --git a/package-deps-graph.png b/package-deps-graph.png index eb8f3b823..746284502 100644 Binary files a/package-deps-graph.png and b/package-deps-graph.png differ