diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c9338c55001604a041d734ca58c67671458b7b51..fe6e951ed121cc905de3b099d8639594dd440795 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -36,99 +36,87 @@ stages: - docker -.build_serial_template: &build_serial_definition - <<: *build_definition - variables: - CTEST_EXCLUDE_LABELS: "longrun" - WALBERLA_BUILD_WITH_MPI: "OFF" - WALBERLA_BUILD_WITH_OPENMP: "OFF" - CMAKE_BUILD_TYPE: "Release" - WALBERLA_BUFFER_DEBUG: "OFF" - WALBERLA_DOUBLE_ACCURACY: "ON" - WALBERLA_BUILD_WITH_METIS: "OFF" - WALBERLA_BUILD_WITH_PARMETIS: "OFF" - - -.build_mpionly_template: &build_mpionly_definition - <<: *build_definition - variables: - CTEST_EXCLUDE_LABELS: "longrun" - WALBERLA_BUILD_WITH_MPI: "ON" - WALBERLA_BUILD_WITH_OPENMP: "OFF" - CMAKE_BUILD_TYPE: "Release" - WALBERLA_BUFFER_DEBUG: "OFF" - WALBERLA_DOUBLE_ACCURACY: "ON" - WALBERLA_BUILD_WITH_METIS: "OFF" - WALBERLA_BUILD_WITH_PARMETIS: "OFF" - - -.build_hybrid_template: &build_hybrid_definition - <<: *build_definition - variables: - CTEST_EXCLUDE_LABELS: "longrun" - WALBERLA_BUILD_WITH_MPI: "ON" - WALBERLA_BUILD_WITH_OPENMP: "ON" - OMP_NUM_THREADS: "4" - OMP_WAIT_POLICY: "PASSIVE" - CMAKE_BUILD_TYPE: "Release" - WALBERLA_BUFFER_DEBUG: "OFF" - WALBERLA_DOUBLE_ACCURACY: "ON" - WALBERLA_BUILD_WITH_METIS: "ON" - WALBERLA_BUILD_WITH_PARMETIS: "ON" - -.build_serial_dbg_template: &build_serial_dbg_definition - <<: *build_definition - variables: - CTEST_EXCLUDE_LABELS: "longrun" - WALBERLA_BUILD_WITH_MPI: "OFF" - WALBERLA_BUILD_WITH_OPENMP: "OFF" - CMAKE_BUILD_TYPE: "DebugOptimized" - WALBERLA_BUFFER_DEBUG: "OFF" - WALBERLA_DOUBLE_ACCURACY: "ON" - WALBERLA_BUILD_WITH_METIS: "OFF" - WALBERLA_BUILD_WITH_PARMETIS: "OFF" - - -.build_mpionly_dbg_template: &build_mpionly_dbg_definition - <<: *build_definition - variables: - CTEST_EXCLUDE_LABELS: "longrun" - WALBERLA_BUILD_WITH_MPI: "ON" - WALBERLA_BUILD_WITH_OPENMP: "OFF" - CMAKE_BUILD_TYPE: "DebugOptimized" - WALBERLA_BUFFER_DEBUG: "OFF" - WALBERLA_DOUBLE_ACCURACY: "ON" - WALBERLA_BUILD_WITH_METIS: "OFF" - WALBERLA_BUILD_WITH_PARMETIS: "OFF" - - -.build_hybrid_dbg_template: &build_hybrid_dbg_definition - <<: *build_definition - variables: - CTEST_EXCLUDE_LABELS: "longrun" - WALBERLA_BUILD_WITH_MPI: "ON" - WALBERLA_BUILD_WITH_OPENMP: "ON" - OMP_NUM_THREADS: "4" - OMP_WAIT_POLICY: "PASSIVE" - CMAKE_BUILD_TYPE: "DebugOptimized" - WALBERLA_BUFFER_DEBUG: "OFF" - WALBERLA_DOUBLE_ACCURACY: "ON" - WALBERLA_BUILD_WITH_METIS: "ON" - WALBERLA_BUILD_WITH_PARMETIS: "ON" - -.build_hybrid_dbg_sp_template: &build_hybrid_dbg_sp_definition - <<: *build_definition - variables: - CTEST_EXCLUDE_LABELS: "longrun" - WALBERLA_BUILD_WITH_MPI: "ON" - WALBERLA_BUILD_WITH_OPENMP: "ON" - OMP_NUM_THREADS: "4" - OMP_WAIT_POLICY: "PASSIVE" - CMAKE_BUILD_TYPE: "DebugOptimized" - WALBERLA_BUFFER_DEBUG: "OFF" - WALBERLA_DOUBLE_ACCURACY: "OFF" - WALBERLA_BUILD_WITH_METIS: "OFF" - WALBERLA_BUILD_WITH_PARMETIS: "OFF" +.variables: &build_serial_variables + CTEST_EXCLUDE_LABELS: "longrun" + WALBERLA_BUILD_WITH_MPI: "OFF" + WALBERLA_BUILD_WITH_OPENMP: "OFF" + CMAKE_BUILD_TYPE: "Release" + WALBERLA_BUFFER_DEBUG: "OFF" + WALBERLA_DOUBLE_ACCURACY: "ON" + WALBERLA_BUILD_WITH_METIS: "OFF" + WALBERLA_BUILD_WITH_PARMETIS: "OFF" + + +.variables: &build_mpionly_variables + CTEST_EXCLUDE_LABELS: "longrun" + WALBERLA_BUILD_WITH_MPI: "ON" + WALBERLA_BUILD_WITH_OPENMP: "OFF" + CMAKE_BUILD_TYPE: "Release" + WALBERLA_BUFFER_DEBUG: "OFF" + WALBERLA_DOUBLE_ACCURACY: "ON" + WALBERLA_BUILD_WITH_METIS: "OFF" + WALBERLA_BUILD_WITH_PARMETIS: "OFF" + + +.variables: &build_hybrid_variables + CTEST_EXCLUDE_LABELS: "longrun" + WALBERLA_BUILD_WITH_MPI: "ON" + WALBERLA_BUILD_WITH_OPENMP: "ON" + OMP_NUM_THREADS: "4" + OMP_WAIT_POLICY: "PASSIVE" + CMAKE_BUILD_TYPE: "Release" + WALBERLA_BUFFER_DEBUG: "OFF" + WALBERLA_DOUBLE_ACCURACY: "ON" + WALBERLA_BUILD_WITH_METIS: "ON" + WALBERLA_BUILD_WITH_PARMETIS: "ON" + + +.variables: &build_serial_dbg_variables + CTEST_EXCLUDE_LABELS: "longrun" + WALBERLA_BUILD_WITH_MPI: "OFF" + WALBERLA_BUILD_WITH_OPENMP: "OFF" + CMAKE_BUILD_TYPE: "DebugOptimized" + WALBERLA_BUFFER_DEBUG: "OFF" + WALBERLA_DOUBLE_ACCURACY: "ON" + WALBERLA_BUILD_WITH_METIS: "OFF" + WALBERLA_BUILD_WITH_PARMETIS: "OFF" + + +.variables: &build_mpionly_dbg_variables + CTEST_EXCLUDE_LABELS: "longrun" + WALBERLA_BUILD_WITH_MPI: "ON" + WALBERLA_BUILD_WITH_OPENMP: "OFF" + CMAKE_BUILD_TYPE: "DebugOptimized" + WALBERLA_BUFFER_DEBUG: "OFF" + WALBERLA_DOUBLE_ACCURACY: "ON" + WALBERLA_BUILD_WITH_METIS: "OFF" + WALBERLA_BUILD_WITH_PARMETIS: "OFF" + + +.variables: &build_hybrid_dbg_variables + CTEST_EXCLUDE_LABELS: "longrun" + WALBERLA_BUILD_WITH_MPI: "ON" + WALBERLA_BUILD_WITH_OPENMP: "ON" + OMP_NUM_THREADS: "4" + OMP_WAIT_POLICY: "PASSIVE" + CMAKE_BUILD_TYPE: "DebugOptimized" + WALBERLA_BUFFER_DEBUG: "OFF" + WALBERLA_DOUBLE_ACCURACY: "ON" + WALBERLA_BUILD_WITH_METIS: "ON" + WALBERLA_BUILD_WITH_PARMETIS: "ON" + + +.variables: &build_hybrid_dbg_sp_variables + CTEST_EXCLUDE_LABELS: "longrun" + WALBERLA_BUILD_WITH_MPI: "ON" + WALBERLA_BUILD_WITH_OPENMP: "ON" + OMP_NUM_THREADS: "4" + OMP_WAIT_POLICY: "PASSIVE" + CMAKE_BUILD_TYPE: "DebugOptimized" + WALBERLA_BUFFER_DEBUG: "OFF" + WALBERLA_DOUBLE_ACCURACY: "OFF" + WALBERLA_BUILD_WITH_METIS: "OFF" + WALBERLA_BUILD_WITH_PARMETIS: "OFF" ############################################################################### @@ -140,573 +128,981 @@ stages: intel_16_serial: - <<: *build_serial_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:16 + variables: + <<: *build_serial_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker - intel intel_16_mpionly: - <<: *build_mpionly_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:16 + variables: + <<: *build_mpionly_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker - intel intel_16_hybrid: - <<: *build_hybrid_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:16 + variables: + <<: *build_hybrid_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker - intel intel_16_serial_dbg: - <<: *build_serial_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:16 + variables: + <<: *build_serial_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker - intel intel_16_mpionly_dbg: - <<: *build_mpionly_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:16 + variables: + <<: *build_mpionly_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker - intel intel_16_hybrid_dbg: - <<: *build_hybrid_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:16 + variables: + <<: *build_hybrid_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "ON" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS tags: - cuda - docker - intel intel_16_hybrid_dbg_sp: - <<: *build_hybrid_dbg_sp_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:16 + variables: + <<: *build_hybrid_dbg_sp_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker - intel intel_17_serial: - <<: *build_serial_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:17 + variables: + <<: *build_serial_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker - intel intel_17_mpionly: - <<: *build_mpionly_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:17 + variables: + <<: *build_mpionly_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker - intel intel_17_hybrid: - <<: *build_hybrid_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:17 + variables: + <<: *build_hybrid_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS tags: - docker - intel intel_17_serial_dbg: - <<: *build_serial_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:17 + variables: + <<: *build_serial_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS tags: - docker - intel intel_17_mpionly_dbg: - <<: *build_mpionly_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:17 + variables: + <<: *build_mpionly_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS tags: - docker - intel intel_17_hybrid_dbg: - <<: *build_hybrid_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:17 + variables: + <<: *build_hybrid_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS tags: - docker - intel intel_17_hybrid_dbg_sp: - <<: *build_hybrid_dbg_sp_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:17 + variables: + <<: *build_hybrid_dbg_sp_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS tags: - docker - intel gcc_5_serial: - <<: *build_serial_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:5 + variables: + <<: *build_serial_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker gcc_5_mpionly: - <<: *build_mpionly_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:5 + variables: + <<: *build_mpionly_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker gcc_5_hybrid: - <<: *build_hybrid_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:5 + variables: + <<: *build_hybrid_variables + WALBERLA_BUILD_WITH_CUDA: "ON" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS tags: - cuda - docker gcc_5_serial_dbg: - <<: *build_serial_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:5 + variables: + <<: *build_serial_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "ON" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS tags: - cuda - docker gcc_5_mpionly_dbg: - <<: *build_mpionly_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:5 + variables: + <<: *build_mpionly_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker gcc_5_hybrid_dbg: - <<: *build_hybrid_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:5 + variables: + <<: *build_hybrid_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "ON" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS tags: - cuda - docker gcc_5_hybrid_dbg_sp: - <<: *build_hybrid_dbg_sp_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:5 + variables: + <<: *build_hybrid_dbg_sp_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker gcc_6_serial: - <<: *build_serial_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:6 + variables: + <<: *build_serial_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker gcc_6_mpionly: - <<: *build_mpionly_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:6 + variables: + <<: *build_mpionly_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker gcc_6_hybrid: - <<: *build_hybrid_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:6 + variables: + <<: *build_hybrid_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker gcc_6_serial_dbg: - <<: *build_serial_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:6 + variables: + <<: *build_serial_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker gcc_6_mpionly_dbg: - <<: *build_mpionly_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:6 + variables: + <<: *build_mpionly_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker gcc_6_hybrid_dbg: - <<: *build_hybrid_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:6 + variables: + <<: *build_hybrid_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker gcc_6_hybrid_dbg_sp: - <<: *build_hybrid_dbg_sp_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:6 + variables: + <<: *build_hybrid_dbg_sp_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker gcc_7_serial: - <<: *build_serial_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:7 + variables: + <<: *build_serial_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker gcc_7_mpionly: - <<: *build_mpionly_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:7 + variables: + <<: *build_mpionly_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker gcc_7_hybrid: - <<: *build_hybrid_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:7 + variables: + <<: *build_hybrid_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS tags: - docker gcc_7_serial_dbg: - <<: *build_serial_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:7 + variables: + <<: *build_serial_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS tags: - docker gcc_7_mpionly_dbg: - <<: *build_mpionly_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:7 + variables: + <<: *build_mpionly_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS tags: - docker gcc_7_hybrid_dbg: - <<: *build_hybrid_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:7 + variables: + <<: *build_hybrid_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS tags: - docker gcc_7_hybrid_dbg_sp: - <<: *build_hybrid_dbg_sp_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:7 + variables: + <<: *build_hybrid_dbg_sp_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS tags: - docker clang_3.6_serial: - <<: *build_serial_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.6 + variables: + <<: *build_serial_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker clang_3.6_mpionly: - <<: *build_mpionly_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.6 + variables: + <<: *build_mpionly_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker clang_3.6_serial_dbg: - <<: *build_serial_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.6 + variables: + <<: *build_serial_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker clang_3.6_mpionly_dbg: - <<: *build_mpionly_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.6 + variables: + <<: *build_mpionly_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "ON" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS tags: - cuda - docker clang_3.7_serial: - <<: *build_serial_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.7 + variables: + <<: *build_serial_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker clang_3.7_mpionly: - <<: *build_mpionly_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.7 + variables: + <<: *build_mpionly_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker clang_3.7_serial_dbg: - <<: *build_serial_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.7 + variables: + <<: *build_serial_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker clang_3.7_mpionly_dbg: - <<: *build_mpionly_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.7 + variables: + <<: *build_mpionly_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker clang_3.8_serial: - <<: *build_serial_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.8 + variables: + <<: *build_serial_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker clang_3.8_mpionly: - <<: *build_mpionly_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.8 + variables: + <<: *build_mpionly_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker clang_3.8_hybrid: - <<: *build_hybrid_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.8 + variables: + <<: *build_hybrid_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker clang_3.8_serial_dbg: - <<: *build_serial_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.8 + variables: + <<: *build_serial_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker clang_3.8_mpionly_dbg: - <<: *build_mpionly_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.8 + variables: + <<: *build_mpionly_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker clang_3.8_hybrid_dbg: - <<: *build_hybrid_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.8 + variables: + <<: *build_hybrid_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker clang_3.8_hybrid_dbg_sp: - <<: *build_hybrid_dbg_sp_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.8 + variables: + <<: *build_hybrid_dbg_sp_variables + WALBERLA_BUILD_WITH_CUDA: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - cuda - docker clang_3.9_serial: - <<: *build_serial_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.9 + variables: + <<: *build_serial_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_3.9_mpionly: - <<: *build_mpionly_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.9 + variables: + <<: *build_mpionly_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_3.9_hybrid: - <<: *build_hybrid_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.9 + variables: + <<: *build_hybrid_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_3.9_serial_dbg: - <<: *build_serial_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.9 + variables: + <<: *build_serial_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_3.9_mpionly_dbg: - <<: *build_mpionly_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.9 + variables: + <<: *build_mpionly_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_3.9_hybrid_dbg: - <<: *build_hybrid_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.9 + variables: + <<: *build_hybrid_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_3.9_hybrid_dbg_sp: - <<: *build_hybrid_dbg_sp_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.9 + variables: + <<: *build_hybrid_dbg_sp_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_4.0_serial: - <<: *build_serial_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:4.0 + variables: + <<: *build_serial_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_4.0_mpionly: - <<: *build_mpionly_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:4.0 + variables: + <<: *build_mpionly_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_4.0_hybrid: - <<: *build_hybrid_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:4.0 + variables: + <<: *build_hybrid_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_4.0_serial_dbg: - <<: *build_serial_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:4.0 + variables: + <<: *build_serial_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_4.0_mpionly_dbg: - <<: *build_mpionly_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:4.0 + variables: + <<: *build_mpionly_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_4.0_hybrid_dbg: - <<: *build_hybrid_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:4.0 + variables: + <<: *build_hybrid_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_4.0_hybrid_dbg_sp: - <<: *build_hybrid_dbg_sp_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:4.0 + variables: + <<: *build_hybrid_dbg_sp_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_5.0_serial: - <<: *build_serial_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:5.0 + variables: + <<: *build_serial_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_5.0_mpionly: - <<: *build_mpionly_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:5.0 + variables: + <<: *build_mpionly_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_5.0_hybrid: - <<: *build_hybrid_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:5.0 + variables: + <<: *build_hybrid_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + only: + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_5.0_serial_dbg: - <<: *build_serial_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:5.0 + variables: + <<: *build_serial_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + only: + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_5.0_mpionly_dbg: - <<: *build_mpionly_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:5.0 + variables: + <<: *build_mpionly_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + only: + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_5.0_hybrid_dbg: - <<: *build_hybrid_dbg_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:5.0 + variables: + <<: *build_hybrid_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + only: + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker clang_5.0_hybrid_dbg_sp: - <<: *build_hybrid_dbg_sp_definition + <<: *build_definition image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:5.0 + variables: + <<: *build_hybrid_dbg_sp_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + only: + variables: + - $ENABLE_NIGHTLY_BUILDS + tags: + - docker + +clang_6.0_serial: + <<: *build_definition + image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:6.0 + variables: + <<: *build_serial_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + only: + variables: + - $ENABLE_NIGHTLY_BUILDS + tags: + - docker + +clang_6.0_mpionly: + <<: *build_definition + image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:6.0 + variables: + <<: *build_mpionly_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + only: + variables: + - $ENABLE_NIGHTLY_BUILDS + tags: + - docker + +clang_6.0_hybrid: + <<: *build_definition + image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:6.0 + variables: + <<: *build_hybrid_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS + tags: + - docker + +clang_6.0_serial_dbg: + <<: *build_definition + image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:6.0 + variables: + <<: *build_serial_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS + tags: + - docker + +clang_6.0_mpionly_dbg: + <<: *build_definition + image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:6.0 + variables: + <<: *build_mpionly_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS + tags: + - docker + +clang_6.0_hybrid_dbg: + <<: *build_definition + image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:6.0 + variables: + <<: *build_hybrid_dbg_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS + tags: + - docker + +clang_6.0_hybrid_dbg_sp: + <<: *build_definition + image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:6.0 + variables: + <<: *build_hybrid_dbg_sp_variables + WALBERLA_BUILD_WITH_CUDA: "OFF" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS tags: - docker @@ -728,6 +1124,9 @@ doc: - cmake .. - cmake . -LAH - make doc + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS tags: - docker artifacts: @@ -752,7 +1151,8 @@ cppcheck: artifacts: untracked: true only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker @@ -780,7 +1180,8 @@ coverage: paths: - coverage/ only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS tags: - docker variables: @@ -821,6 +1222,9 @@ msvc-14_Hybrid_Dbg: WALBERLA_BUILD_WITH_MPI: "ON" WALBERLA_BUILD_WITH_OPENMP: "ON" WALBERLA_DOUBLE_ACCURACY: "ON" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS msvc-14_Hybrid_SP_Dbg: <<: *win_build_definition @@ -832,7 +1236,8 @@ msvc-14_Hybrid_SP_Dbg: WALBERLA_BUILD_WITH_OPENMP: "ON" WALBERLA_DOUBLE_ACCURACY: "OFF" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS msvc-14_Hybrid: <<: *win_build_definition @@ -844,7 +1249,8 @@ msvc-14_Hybrid: WALBERLA_BUILD_WITH_OPENMP: "ON" WALBERLA_DOUBLE_ACCURACY: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS msvc-14_Serial_Dbg: <<: *win_build_definition @@ -856,7 +1262,8 @@ msvc-14_Serial_Dbg: WALBERLA_BUILD_WITH_OPENMP: "OFF" WALBERLA_DOUBLE_ACCURACY: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS msvc-14_Serial: <<: *win_build_definition @@ -868,7 +1275,8 @@ msvc-14_Serial: WALBERLA_BUILD_WITH_OPENMP: "OFF" WALBERLA_DOUBLE_ACCURACY: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS msvc-14_MpiOnly_Dbg: <<: *win_build_definition @@ -880,7 +1288,8 @@ msvc-14_MpiOnly_Dbg: WALBERLA_BUILD_WITH_OPENMP: "OFF" WALBERLA_DOUBLE_ACCURACY: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS msvc-14_MpiOnly: <<: *win_build_definition @@ -892,7 +1301,8 @@ msvc-14_MpiOnly: WALBERLA_BUILD_WITH_OPENMP: "OFF" WALBERLA_DOUBLE_ACCURACY: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS msvc-14.1_Hybrid_Dbg: @@ -904,6 +1314,9 @@ msvc-14.1_Hybrid_Dbg: WALBERLA_BUILD_WITH_MPI: "ON" WALBERLA_BUILD_WITH_OPENMP: "ON" WALBERLA_DOUBLE_ACCURACY: "ON" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS msvc-14.1_Hybrid_SP_Dbg: <<: *win_build_definition @@ -914,6 +1327,9 @@ msvc-14.1_Hybrid_SP_Dbg: WALBERLA_BUILD_WITH_MPI: "ON" WALBERLA_BUILD_WITH_OPENMP: "ON" WALBERLA_DOUBLE_ACCURACY: "OFF" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS msvc-14.1_Hybrid: <<: *win_build_definition @@ -924,6 +1340,9 @@ msvc-14.1_Hybrid: WALBERLA_BUILD_WITH_MPI: "ON" WALBERLA_BUILD_WITH_OPENMP: "ON" WALBERLA_DOUBLE_ACCURACY: "ON" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS msvc-14.1_Serial_Dbg: <<: *win_build_definition @@ -934,6 +1353,9 @@ msvc-14.1_Serial_Dbg: WALBERLA_BUILD_WITH_MPI: "OFF" WALBERLA_BUILD_WITH_OPENMP: "OFF" WALBERLA_DOUBLE_ACCURACY: "ON" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS msvc-14.1_Serial: <<: *win_build_definition @@ -945,7 +1367,8 @@ msvc-14.1_Serial: WALBERLA_BUILD_WITH_OPENMP: "OFF" WALBERLA_DOUBLE_ACCURACY: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS msvc-14.1_MpiOnly_Dbg: <<: *win_build_definition @@ -956,6 +1379,9 @@ msvc-14.1_MpiOnly_Dbg: WALBERLA_BUILD_WITH_MPI: "ON" WALBERLA_BUILD_WITH_OPENMP: "OFF" WALBERLA_DOUBLE_ACCURACY: "ON" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS msvc-14.1_MpiOnly: <<: *win_build_definition @@ -967,7 +1393,8 @@ msvc-14.1_MpiOnly: WALBERLA_BUILD_WITH_OPENMP: "OFF" WALBERLA_DOUBLE_ACCURACY: "ON" only: - - triggers + variables: + - $ENABLE_NIGHTLY_BUILDS ############################################################################### @@ -990,7 +1417,7 @@ msvc-14.1_MpiOnly: - cmake .. -DWALBERLA_BUILD_TESTS=ON -DWALBERLA_BUILD_BENCHMARKS=ON -DWALBERLA_BUILD_TUTORIALS=ON -DWALBERLA_BUILD_TOOLS=ON -DWALBERLA_BUILD_WITH_MPI=$WALBERLA_BUILD_WITH_MPI -DWALBERLA_BUILD_WITH_PYTHON=$WALBERLA_BUILD_WITH_PYTHON -DWALBERLA_BUILD_WITH_OPENMP=$WALBERLA_BUILD_WITH_OPENMP -DWALBERLA_BUILD_WITH_CUDA=$WALBERLA_BUILD_WITH_CUDA -DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -DWARNING_ERROR=ON - cmake . -LAH - make -j $NUM_BUILD_CORES -l $NUM_CORES - - ctest -LE $CTEST_EXCLUDE_LABELS -C $CMAKE_BUILD_TYPE --output-on-failure -j $NUM_CORES + - ctest -LE "$CTEST_EXCLUDE_LABELS|cuda" -C $CMAKE_BUILD_TYPE --output-on-failure -j $NUM_CORES tags: - mac @@ -998,41 +1425,53 @@ mac_Serial_Dbg: <<: *mac_build_definition variables: CMAKE_BUILD_TYPE: "DebugOptimized" - CTEST_EXCLUDE_LABELS: "longrun|cuda" + CTEST_EXCLUDE_LABELS: "longrun" WALBERLA_BUILD_WITH_MPI: "OFF" WALBERLA_BUILD_WITH_OPENMP: "OFF" WALBERLA_BUILD_WITH_PYTHON: "ON" WALBERLA_BUILD_WITH_CUDA: "ON" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS mac_Serial: <<: *mac_build_definition variables: CMAKE_BUILD_TYPE: "Release" - CTEST_EXCLUDE_LABELS: "longrun|cuda" + CTEST_EXCLUDE_LABELS: "longrun" WALBERLA_BUILD_WITH_MPI: "OFF" WALBERLA_BUILD_WITH_OPENMP: "OFF" WALBERLA_BUILD_WITH_PYTHON: "ON" WALBERLA_BUILD_WITH_CUDA: "ON" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS mac_MpiOnly_Dbg: <<: *mac_build_definition variables: CMAKE_BUILD_TYPE: "DebugOptimized" - CTEST_EXCLUDE_LABELS: "longrun|cuda" + CTEST_EXCLUDE_LABELS: "longrun" WALBERLA_BUILD_WITH_MPI: "ON" WALBERLA_BUILD_WITH_OPENMP: "OFF" WALBERLA_BUILD_WITH_PYTHON: "ON" WALBERLA_BUILD_WITH_CUDA: "ON" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS mac_MpiOnly: <<: *mac_build_definition variables: CMAKE_BUILD_TYPE: "Release" - CTEST_EXCLUDE_LABELS: "longrun|cuda" + CTEST_EXCLUDE_LABELS: "longrun" WALBERLA_BUILD_WITH_MPI: "ON" WALBERLA_BUILD_WITH_OPENMP: "OFF" WALBERLA_BUILD_WITH_PYTHON: "ON" WALBERLA_BUILD_WITH_CUDA: "ON" + except: + variables: + - $DISABLE_PER_COMMIT_BUILDS ############################################################################### @@ -1089,3 +1528,64 @@ conda-py35-linux: - apt-get update - apt-get install -y build-essential - conda build --python=3.5 --user=lssfau utilities/conda/walberla + + +############################################################################### +## ## +## Benchmarks ## +## ## +############################################################################### + +.benchmark_template: &benchmark_definition + script: + - apt-get update --fix-missing + - apt-get install -y python3-influxdb python3-git + - $CXX --version + - cmake --version + - ccache --version + - mpirun --version + - export CCACHE_BASEDIR=$CI_PROJECT_DIR + - mkdir $CI_PROJECT_DIR/build + - cd $CI_PROJECT_DIR/build + - cmake .. -DWALBERLA_BUFFER_DEBUG=OFF -DWALBERLA_BUILD_TESTS=OFF -DWALBERLA_BUILD_BENCHMARKS=ON -DWALBERLA_BUILD_TUTORIALS=OFF -DWALBERLA_BUILD_TOOLS=OFF -DWALBERLA_BUILD_WITH_MPI=ON -DWALBERLA_BUILD_WITH_CUDA=OFF -DWALBERLA_BUILD_WITH_PYTHON=OFF -DWALBERLA_BUILD_WITH_OPENMP=OFF -DCMAKE_BUILD_TYPE=RELEASE -DMPIEXEC_PREFLAGS=$MPIEXEC_PREFLAGS -DWALBERLA_DOUBLE_ACCURACY=ON -DWARNING_ERROR=ON -DWALBERLA_BUILD_WITH_METIS=OFF -DWALBERLA_BUILD_WITH_PARMETIS=OFF -DWALBERLA_OPTIMIZE_FOR_LOCALHOST=ON -DWALBERLA_BUILD_WITH_FASTMATH=ON -DWALBERLA_BUILD_WITH_LTO=ON + - cmake . -LAH + - cd apps/benchmarks/PeriodicGranularGas + - make -j 20 + - export PATH=$PATH:/usr/local/likwid/bin + - likwid-setFrequencies -t 0 + - likwid-setFrequencies -g performance + - likwid-setFrequencies -x 3.3 -y 3.3 # set frequency to 3.3 + - mpirun --allow-run-as-root -np 8 --map-by core --bind-to core --report-bindings ./PeriodicGranularGas PeriodicGranularGas.cfg --DEM --syncNextNeighbor | tee PeriodicGranularGas_DEM_NN.txt + - mpirun --allow-run-as-root -np 8 --map-by core --bind-to core --report-bindings ./PeriodicGranularGas PeriodicGranularGas.cfg --DEM --syncShadowOwners | tee PeriodicGranularGas_DEM_SO.txt + - mpirun --allow-run-as-root -np 8 --map-by core --bind-to core --report-bindings ./PeriodicGranularGas PeriodicGranularGas.cfg --HCSITS --syncNextNeighbor --InelasticFrictionlessContact | tee PeriodicGranularGas_HCSITS_NN_IFC.txt + - mpirun --allow-run-as-root -np 8 --map-by core --bind-to core --report-bindings ./PeriodicGranularGas PeriodicGranularGas.cfg --HCSITS --syncNextNeighbor --ApproximateInelasticCoulombContactByDecoupling | tee PeriodicGranularGas_HCSITS_NN_AICCBD.txt + - mpirun --allow-run-as-root -np 8 --map-by core --bind-to core --report-bindings ./PeriodicGranularGas PeriodicGranularGas.cfg --HCSITS --syncNextNeighbor --InelasticCoulombContactByDecoupling | tee PeriodicGranularGas_HCSITS_NN_ICCBD.txt + - mpirun --allow-run-as-root -np 8 --map-by core --bind-to core --report-bindings ./PeriodicGranularGas PeriodicGranularGas.cfg --HCSITS --syncNextNeighbor --InelasticGeneralizedMaximumDissipationContact | tee PeriodicGranularGas_HCSITS_NN_IGMDC.txt + - mpirun --allow-run-as-root -np 8 --map-by core --bind-to core --report-bindings ./PeriodicGranularGas PeriodicGranularGas.cfg --HCSITS --syncShadowOwners --InelasticFrictionlessContact | tee PeriodicGranularGas_HCSITS_SO_IFC.txt + - python3 upload.py + only: + variables: + - $ENABLE_BENCHMARKS + tags: + - docker-benchmark + artifacts: + paths: + - $CI_PROJECT_DIR/build/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas_DEM_NN.txt + - $CI_PROJECT_DIR/build/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas_DEM_SO.txt + - $CI_PROJECT_DIR/build/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas_HCSITS_NN_IFC.txt + - $CI_PROJECT_DIR/build/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas_HCSITS_NN_AICCBD.txt + - $CI_PROJECT_DIR/build/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas_HCSITS_NN_ICCBD.txt + - $CI_PROJECT_DIR/build/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas_HCSITS_NN_IGMDC.txt + - $CI_PROJECT_DIR/build/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas_HCSITS_SO_IFC.txt + +benchmark_intel17: + <<: *benchmark_definition + image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:17 + +benchmark_gcc7: + <<: *benchmark_definition + image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:7 + +benchmark_clang6: + <<: *benchmark_definition + image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:6.0 \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 85125dcaf83ccf81a7ef108eb38f92b4b3ee89ed..0ee1e578c7a963ec1f5f40c907fce8aa647b1b6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1027,31 +1027,22 @@ endif() option ( WALBERLA_THREAD_SAFE_LOGGING "Enables/Disables thread-safe logging" ON ) if ( WALBERLA_BUILD_WITH_OPENMP ) - if ( WALBERLA_CXX_COMPILER_IS_INTEL ) + if ( WALBERLA_CXX_COMPILER_IS_INTEL AND "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "16.0.3" ) add_flag ( CMAKE_C_FLAGS "-openmp" ) add_flag ( CMAKE_CXX_FLAGS "-openmp" ) - elseif ( CMAKE_COMPILER_IS_GNUCXX ) - add_flag ( CMAKE_C_FLAGS "-fopenmp" ) - add_flag ( CMAKE_CXX_FLAGS "-fopenmp" ) - elseif ( WALBERLA_CXX_COMPILER_IS_CLANG ) - add_flag ( CMAKE_C_FLAGS "-fopenmp" ) - add_flag ( CMAKE_CXX_FLAGS "-fopenmp" ) - elseif ( WALBERLA_CXX_COMPILER_IS_MSVC ) - add_flag ( CMAKE_C_FLAGS "/openmp" ) - add_flag ( CMAKE_CXX_FLAGS "/openmp" ) - elseif ( WALBERLA_CXX_COMPILER_IS_IBM ) - add_flag ( CMAKE_C_FLAGS "-qsmp=omp" ) - add_flag ( CMAKE_CXX_FLAGS "-qsmp=omp" ) - # There has been an internal compiler error with the IBM compiler, so WALBERLA_THREAD_SAFE_LOGGING is disabled by default for this compiler - set ( WALBERLA_THREAD_SAFE_LOGGING OFF CACHE BOOL "Enables/Disables thread-safe logging" FORCE ) elseif ( WALBERLA_CXX_COMPILER_IS_NEC ) - add_flag ( CMAKE_C_FLAGS "-Popenmp" ) - add_flag ( CMAKE_CXX_FLAGS "-Popenmp" ) + add_flag ( CMAKE_C_FLAGS "-Popenmp" ) + add_flag ( CMAKE_CXX_FLAGS "-Popenmp" ) + else() + find_package( OpenMP ) + add_flag ( CMAKE_C_FLAGS "${OpenMP_C_FLAGS}" ) + add_flag ( CMAKE_CXX_FLAGS "${OpenMP_CXX_FLAGS}" ) + list ( APPEND SERVICE_LIBS ${OpenMP_CXX_LIBRARIES} ) endif() else() if ( WALBERLA_CXX_COMPILER_IS_CRAY ) - add_flag ( CMAKE_C_FLAGS "-h noomp" ) - add_flag ( CMAKE_CXX_FLAGS "-h noomp" ) + add_flag ( CMAKE_C_FLAGS "-h noomp" ) + add_flag ( CMAKE_CXX_FLAGS "-h noomp" ) endif() endif() ############################################################################################################################ diff --git a/apps/benchmarks/CMakeLists.txt b/apps/benchmarks/CMakeLists.txt index 47f77911653f7c8eec3d68550711810a8606e153..a81420b475e6378a3f453ebd4ae16c2c0c895e8d 100644 --- a/apps/benchmarks/CMakeLists.txt +++ b/apps/benchmarks/CMakeLists.txt @@ -4,6 +4,7 @@ add_subdirectory( CouetteFlow ) add_subdirectory( ForcesOnSphereNearPlaneInShearFlow ) add_subdirectory( NonUniformGrid ) add_subdirectory( MotionSingleHeavySphere ) +add_subdirectory( PeriodicGranularGas ) add_subdirectory( PoiseuilleChannel ) add_subdirectory( SchaeferTurek ) -add_subdirectory( UniformGrid ) \ No newline at end of file +add_subdirectory( UniformGrid ) diff --git a/apps/benchmarks/ComplexGeometry/test.conf b/apps/benchmarks/ComplexGeometry/test.conf index 4279c514f08abb430d63735905e4433d8fc53f73..1b43bfc4e6f1dfe2eff8953a1680cbf68b5f6b97 100644 --- a/apps/benchmarks/ComplexGeometry/test.conf +++ b/apps/benchmarks/ComplexGeometry/test.conf @@ -1,12 +1,12 @@ ComplexGeometry { meshFile cube.obj; - coarseDx 0.2; + coarseDx 0.1; coarseOmega 1.6; coarseTimeSteps 1; numLevels 2; bodyForce <0.0001, 0, 0>; - blockSize <8,8,8>; + blockSize <16,16,16>; domainBlowUp <5,5,5>; // simulation domain is blow up factor times mesh size per dimension Boundaries { diff --git a/apps/benchmarks/CouetteFlow/CouetteFlow.cpp b/apps/benchmarks/CouetteFlow/CouetteFlow.cpp index 815e6cdf1504ad4fdab43a6bcb3bc351363a7ba9..b28601c50d2ce89cb65425fd707588387a2e1053 100644 --- a/apps/benchmarks/CouetteFlow/CouetteFlow.cpp +++ b/apps/benchmarks/CouetteFlow/CouetteFlow.cpp @@ -91,7 +91,6 @@ #include "vtk/Initialization.h" #include "vtk/VTKOutput.h" -#include <boost/bind.hpp> #include <boost/mpl/or.hpp> #include <boost/type_traits/is_same.hpp> @@ -99,6 +98,7 @@ #include <cmath> #include <cstdlib> #include <cstring> +#include <functional> #include <iostream> #include <utility> #include <vector> @@ -241,7 +241,7 @@ class BorderRefinementSelection public: BorderRefinementSelection( const Setup & setup, const uint_t level, const real_t bufferDistance ) : - setup_( setup ), level_( level ), bufferDistance_( bufferDistance ) {} + setup_( setup ), level_( level ), bufferDistance_( bufferDistance ) { WALBERLA_UNUSED(setup_); } void operator()( SetupBlockForest & forest ) { @@ -294,7 +294,7 @@ static shared_ptr< SetupBlockForest > createSetupBlockForest( const blockforest: ( setup.zCells + uint_t(2) * FieldGhostLayers ) ) * memoryPerCell; forest->addRefinementSelectionFunction( refinementSelectionFunctions ); - forest->addWorkloadMemorySUIDAssignmentFunction( boost::bind( workloadAndMemoryAssignment, _1, memoryPerBlock ) ); + forest->addWorkloadMemorySUIDAssignmentFunction( std::bind( workloadAndMemoryAssignment, std::placeholders::_1, memoryPerBlock ) ); forest->init( AABB( real_c(0), real_c(0), real_c(0), real_c( setup.xBlocks * setup.xCells ), real_c( setup.yBlocks * setup.yCells ), @@ -736,11 +736,11 @@ void run( const shared_ptr< Config > & config, const LatticeModel_T & latticeMod // evaluation - const auto exactSolutionFunction = boost::bind( exactVelocity, _1, blocks->getDomain(), setup.maxVelocity_L ); + const auto exactSolutionFunction = std::bind( exactVelocity, std::placeholders::_1, blocks->getDomain(), setup.maxVelocity_L ); auto volumetricFlowRate = field::makeVolumetricFlowRateEvaluation< VelocityAdaptor_T, FlagField_T >( configBlock, blocks, velocityAdaptorId, flagFieldId, Fluid_Flag, - boost::bind( exactFlowRate, setup.flowRate_L ), + std::bind( exactFlowRate, setup.flowRate_L ), exactSolutionFunction ); volumetricFlowRate->setNormalizationFactor( real_t(1) / setup.maxVelocity_L ); volumetricFlowRate->setDomainNormalization( Vector3<real_t>( real_t(1) ) ); diff --git a/apps/benchmarks/ForcesOnSphereNearPlaneInShearFlow/ForcesOnSphereNearPlaneInShearFlow.cpp b/apps/benchmarks/ForcesOnSphereNearPlaneInShearFlow/ForcesOnSphereNearPlaneInShearFlow.cpp index 62cd5258d085e029eedce2f53940177244d7d187..64bc164815b875e0bfeb4774bdae1ecef440e514 100644 --- a/apps/benchmarks/ForcesOnSphereNearPlaneInShearFlow/ForcesOnSphereNearPlaneInShearFlow.cpp +++ b/apps/benchmarks/ForcesOnSphereNearPlaneInShearFlow/ForcesOnSphereNearPlaneInShearFlow.cpp @@ -62,6 +62,8 @@ #include "field/vtk/all.h" #include "lbm/vtk/all.h" +#include <functional> + namespace forces_on_sphere_near_plane_in_shear_flow { @@ -177,7 +179,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( const AABB & do WALBERLA_LOG_INFO_ON_ROOT(" - refinement box: " << refinementBox); - sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, numberOfLevels, refinementBox ) ); + sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, numberOfLevels, refinementBox ) ); sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment ); sforest.init( domainAABB, numberOfCoarseBlocksPerDirection[0], numberOfCoarseBlocksPerDirection[1], numberOfCoarseBlocksPerDirection[2], true, true, false ); @@ -576,7 +578,7 @@ int main( int argc, char **argv ) // set up synchronization procedure const real_t overlap = real_t( 1.5 ) * dx; - std::function<void(void)> syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); + std::function<void(void)> syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); // create pe bodies diff --git a/apps/benchmarks/MotionSingleHeavySphere/MotionSingleHeavySphere.cpp b/apps/benchmarks/MotionSingleHeavySphere/MotionSingleHeavySphere.cpp index fc6a084ffb1451de776451618b6d60e4c1873040..825af2b2ddf3214a788d4bda7bc80656599f30f7 100644 --- a/apps/benchmarks/MotionSingleHeavySphere/MotionSingleHeavySphere.cpp +++ b/apps/benchmarks/MotionSingleHeavySphere/MotionSingleHeavySphere.cpp @@ -58,6 +58,7 @@ #include "vtk/Initialization.h" #include "vtk/VTKOutput.h" +#include <functional> #include <memory> @@ -811,9 +812,9 @@ int main( int argc, char **argv ) const real_t overlap = real_t( 1.5 ) * dx; std::function<void(void)> syncCall; if( XBlocks <= uint_t(4) ) - syncCall = boost::bind( pe::syncNextNeighbors<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); + syncCall = std::bind( pe::syncNextNeighbors<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); else - syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); + syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); real_t xParticle = real_t(0); diff --git a/apps/benchmarks/NonUniformGrid/NonUniformGrid.cpp b/apps/benchmarks/NonUniformGrid/NonUniformGrid.cpp index 38057f0f3d602175851e763e5a4b416c04701a8b..0602976bcbc2de7b99e78de14d9335d5bf8bbeb4 100644 --- a/apps/benchmarks/NonUniformGrid/NonUniformGrid.cpp +++ b/apps/benchmarks/NonUniformGrid/NonUniformGrid.cpp @@ -76,6 +76,7 @@ #include "vtk/VTKOutput.h" #include <cstdlib> +#include <functional> #include <iostream> @@ -279,7 +280,7 @@ void createSetupBlockForest( blockforest::SetupBlockForest & sforest, const Conf uint_c( 19 * sizeof(real_t) ) ) / numeric_cast< memory_t >( 1024 * 1024 ); sforest.addRefinementSelectionFunction( refinementSelection ); - sforest.addWorkloadMemorySUIDAssignmentFunction( boost::bind( workloadAndMemoryAssignment, _1, memoryPerBlock ) ); + sforest.addWorkloadMemorySUIDAssignmentFunction( std::bind( workloadAndMemoryAssignment, std::placeholders::_1, memoryPerBlock ) ); sforest.init( AABB( real_t(0), real_t(0), real_t(0), real_c( numberOfXBlocks * numberOfXCellsPerBlock ), real_c( numberOfYBlocks * numberOfYCellsPerBlock ), diff --git a/apps/benchmarks/PeriodicGranularGas/CMakeLists.txt b/apps/benchmarks/PeriodicGranularGas/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..d26f6314fd3d73bbac01b460da7240949a45350a --- /dev/null +++ b/apps/benchmarks/PeriodicGranularGas/CMakeLists.txt @@ -0,0 +1,6 @@ +waLBerla_link_files_to_builddir( *.cfg ) +waLBerla_link_files_to_builddir( *.py ) + +waLBerla_add_executable ( NAME PeriodicGranularGas + FILES PeriodicGranularGas.cpp + DEPENDS blockforest core pe ) diff --git a/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas.cfg b/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas.cfg new file mode 100644 index 0000000000000000000000000000000000000000..e281e9b0ecd0abe2ee48313040696d09d86d9db1 --- /dev/null +++ b/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas.cfg @@ -0,0 +1,22 @@ + +PeriodicGranularGas +{ + simulationCorner < 0, 0, 0 >; + simulationDomain < 30, 30, 30 >; + blocks < 2, 2, 2 >; + isPeriodic < 1, 1, 1 >; + + radius 0.5; + spacing 1.0; + vMax 0.0; + + dt 0.1; + simulationSteps 1000; + visSpacing 100; + + HCSITSmaxIterations 10; + HCSITSRelaxationParameter 0.7; + HCSITSErrorReductionParameter 0.8; + HCSITSRelaxationModelStr ApproximateInelasticCoulombContactByDecoupling; + globalLinearAcceleration < 0, 0, 0 >; +} diff --git a/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas.cpp b/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7efaeb660c56c92b7467a83b17312125fa403d19 --- /dev/null +++ b/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas.cpp @@ -0,0 +1,250 @@ +//====================================================================================================================== +// +// This file is part of waLBerla. waLBerla is free software: you can +// redistribute it and/or modify it under the terms of the GNU General Public +// License as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// waLBerla is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. +// +//! \file PeriodicGranularGas.cpp +//! \author Sebastian Eibl <sebastian.eibl@fau.de> +// +//====================================================================================================================== + +#include <pe/basic.h> +#include <pe/vtk/SphereVtkOutput.h> + +#include <core/Abort.h> +#include <core/Environment.h> +#include <core/grid_generator/SCIterator.h> +#include <core/logging/Logging.h> +#include <core/waLBerlaBuildInfo.h> +#include <vtk/VTKOutput.h> + +#include <functional> +#include <memory> + +using namespace walberla; +using namespace walberla::pe; +using namespace walberla::timing; + +typedef boost::tuple<Sphere> BodyTuple ; + +int main( int argc, char ** argv ) +{ + Environment env(argc, argv); + + logging::Logging::instance()->setStreamLogLevel(logging::Logging::INFO); + logging::Logging::instance()->setFileLogLevel(logging::Logging::INFO); + + WALBERLA_LOG_INFO_ON_ROOT( "config file: " << argv[1] ) + WALBERLA_LOG_INFO_ON_ROOT( "waLBerla Revision: " << WALBERLA_GIT_SHA1 ); + + math::seedRandomGenerator( static_cast<unsigned int>(1337 * mpi::MPIManager::instance()->worldRank()) ); + + WALBERLA_LOG_INFO_ON_ROOT("*** READING COMMANDLINE ARGUMENTS ***"); + bool bDEM = false; + bool bHCSITS = false; + + bool bNN = false; + bool bSO = false; + + bool bInelasticFrictionlessContact = false; + bool bApproximateInelasticCoulombContactByDecoupling = false; + bool bInelasticCoulombContactByDecoupling = false; + bool bInelasticGeneralizedMaximumDissipationContact = false; + + for( int i = 1; i < argc; ++i ) + { + if( std::strcmp( argv[i], "--DEM" ) == 0 ) bDEM = true; + if( std::strcmp( argv[i], "--HCSITS" ) == 0 ) bHCSITS = true; + + if( std::strcmp( argv[i], "--syncNextNeighbor" ) == 0 ) bNN = true; + if( std::strcmp( argv[i], "--syncShadowOwners" ) == 0 ) bSO = true; + + if( std::strcmp( argv[i], "--InelasticFrictionlessContact" ) == 0 ) bInelasticFrictionlessContact = true; + if( std::strcmp( argv[i], "--ApproximateInelasticCoulombContactByDecoupling" ) == 0 ) bApproximateInelasticCoulombContactByDecoupling = true; + if( std::strcmp( argv[i], "--InelasticCoulombContactByDecoupling" ) == 0 ) bInelasticCoulombContactByDecoupling = true; + if( std::strcmp( argv[i], "--InelasticGeneralizedMaximumDissipationContact" ) == 0 ) bInelasticGeneralizedMaximumDissipationContact = true; + } + + WALBERLA_LOG_INFO_ON_ROOT("*** READING CONFIG FILE ***"); + auto cfg = env.config(); + if (cfg == NULL) WALBERLA_ABORT("No config specified!"); + const Config::BlockHandle mainConf = cfg->getBlock( "PeriodicGranularGas" ); + + int simulationSteps = mainConf.getParameter<int>("simulationSteps", 10 ); + WALBERLA_LOG_INFO_ON_ROOT("simulationSteps: " << simulationSteps); + + real_t dt = mainConf.getParameter<real_t>("dt", real_c(0.01) ); + WALBERLA_LOG_INFO_ON_ROOT("dt: " << dt); + + const int visSpacing = mainConf.getParameter<int>("visSpacing", 1000 ); + WALBERLA_LOG_INFO_ON_ROOT("visSpacing: " << visSpacing); + const std::string path = mainConf.getParameter<std::string>("path", "vtk_out" ); + WALBERLA_LOG_INFO_ON_ROOT("path: " << path); + + WALBERLA_LOG_INFO_ON_ROOT("*** GLOBALBODYSTORAGE ***"); + shared_ptr<BodyStorage> globalBodyStorage = make_shared<BodyStorage>(); + + WALBERLA_LOG_INFO_ON_ROOT("*** BLOCKFOREST ***"); + // create forest + shared_ptr< BlockForest > forest = createBlockForestFromConfig( mainConf ); + if (!forest) + { + WALBERLA_LOG_INFO_ON_ROOT( "No BlockForest created ... exiting!"); + return EXIT_SUCCESS; + } + + WALBERLA_LOG_INFO_ON_ROOT("simulationDomain: " << forest->getDomain()); + + WALBERLA_LOG_INFO_ON_ROOT("blocks: " << Vector3<uint_t>(forest->getXSize(), forest->getYSize(), forest->getZSize()) ); + + WALBERLA_LOG_INFO_ON_ROOT("*** BODYTUPLE ***"); + // initialize body type ids + SetBodyTypeIDs<BodyTuple>::execute(); + + WALBERLA_LOG_INFO_ON_ROOT("*** STORAGEDATAHANDLING ***"); + // add block data + auto storageID = forest->addBlockData(createStorageDataHandling<BodyTuple>(), "Storage"); + auto ccdID = forest->addBlockData(ccd::createHashGridsDataHandling( globalBodyStorage, storageID ), "CCD"); + auto fcdID = forest->addBlockData(fcd::createGenericFCDDataHandling<BodyTuple, fcd::AnalyticCollideFunctor>(), "FCD"); + + WALBERLA_LOG_INFO_ON_ROOT("*** INTEGRATOR ***"); + std::unique_ptr<cr::ICR> cr; + if (bDEM) + { + cr = std::make_unique<cr::DEM>(globalBodyStorage, forest, storageID, ccdID, fcdID); + WALBERLA_LOG_INFO_ON_ROOT("Using DEM!"); + } else if (bHCSITS) + { + cr = std::make_unique<cr::HCSITS>(globalBodyStorage, forest, storageID, ccdID, fcdID); + configure(mainConf, *static_cast<cr::HCSITS*>(cr.get())); + WALBERLA_LOG_INFO_ON_ROOT("Using HCSITS!"); + + cr::HCSITS* hcsits = static_cast<cr::HCSITS*>(cr.get()); + + if (bInelasticFrictionlessContact) + { + hcsits->setRelaxationModel(cr::HCSITS::InelasticFrictionlessContact); + WALBERLA_LOG_INFO_ON_ROOT("Using InelasticFrictionlessContact!"); + } else if (bApproximateInelasticCoulombContactByDecoupling) + { + hcsits->setRelaxationModel(cr::HCSITS::ApproximateInelasticCoulombContactByDecoupling); + WALBERLA_LOG_INFO_ON_ROOT("Using ApproximateInelasticCoulombContactByDecoupling!"); + } else if (bInelasticCoulombContactByDecoupling) + { + hcsits->setRelaxationModel(cr::HCSITS::InelasticCoulombContactByDecoupling); + WALBERLA_LOG_INFO_ON_ROOT("Using InelasticCoulombContactByDecoupling!"); + } else if (bInelasticGeneralizedMaximumDissipationContact) + { + hcsits->setRelaxationModel(cr::HCSITS::InelasticGeneralizedMaximumDissipationContact); + WALBERLA_LOG_INFO_ON_ROOT("Using InelasticGeneralizedMaximumDissipationContact!"); + } else + { + WALBERLA_ABORT("Friction model could not be determined!"); + } + } else + { + WALBERLA_ABORT("Model could not be determined!"); + } + + WALBERLA_LOG_INFO_ON_ROOT("*** SYNCCALL ***"); + std::function<void(void)> syncCallWithoutTT; + if (bNN) + { + syncCallWithoutTT = std::bind( pe::syncNextNeighbors<BodyTuple>, boost::ref(*forest), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false ); + WALBERLA_LOG_INFO_ON_ROOT("Using NextNeighbor sync!"); + } else if (bSO) + { + syncCallWithoutTT = std::bind( pe::syncShadowOwners<BodyTuple>, boost::ref(*forest), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false ); + WALBERLA_LOG_INFO_ON_ROOT("Using ShadowOwner sync!"); + } else + { + WALBERLA_ABORT("Synchronization method could not be determined!"); + } + + WALBERLA_LOG_INFO_ON_ROOT("*** VTK ***"); + auto vtkDomainOutput = vtk::createVTKOutput_DomainDecomposition( forest, "domain_decomposition", 1, "vtk_out", "simulation_step" ); + auto vtkSphereHelper = make_shared<SphereVtkOutput>(storageID, *forest) ; + auto vtkSphereOutput = vtk::createVTKOutput_PointData(vtkSphereHelper, "Bodies", 1, "vtk_out", "simulation_step", false, false); + + WALBERLA_LOG_INFO_ON_ROOT("*** SETUP - START ***"); + const real_t static_cof ( real_c(0.1) / 2 ); // Coefficient of static friction. Note: pe doubles the input coefficient of friction for material-material contacts. + const real_t dynamic_cof ( static_cof ); // Coefficient of dynamic friction. Similar to static friction for low speed friction. + MaterialID material = createMaterial( "granular", real_t( 1.0 ), 0, static_cof, dynamic_cof, real_t( 0.5 ), 1, 1, 0, 0 ); + + auto simulationDomain = forest->getDomain(); + auto generationDomain = simulationDomain; // simulationDomain.getExtended(-real_c(0.5) * spacing); + + const real_t spacing(1.0); + const real_t radius(0.5); + uint_t numParticles = uint_c(0); + + for (auto& currentBlock : *forest) + { + for (auto it = grid_generator::SCIterator(currentBlock.getAABB().getIntersection(generationDomain), Vector3<real_t>(spacing, spacing, spacing) * real_c(0.5), spacing); it != grid_generator::SCIterator(); ++it) + { + SphereID sp = pe::createSphere( *globalBodyStorage, *forest, storageID, 0, *it, radius, material); + if (sp != NULL) ++numParticles; + } + } + mpi::reduceInplace(numParticles, mpi::SUM); + WALBERLA_LOG_INFO_ON_ROOT("#particles created: " << numParticles); + + WALBERLA_LOG_INFO_ON_ROOT("*** SETUP - END ***"); + + // synchronize particles + syncCallWithoutTT(); + syncCallWithoutTT(); + + WALBERLA_LOG_INFO_ON_ROOT("*** SIMULATION - START ***"); + WALBERLA_MPI_BARRIER(); + WcTimer timer; + for (int i=0; i < simulationSteps; ++i) + { + if( i % 200 == 0 ) + { + WALBERLA_LOG_DEVEL_ON_ROOT( "Timestep " << i << " / " << simulationSteps ); + } + + cr->timestep( real_c(dt) ); + syncCallWithoutTT(); + +// if( i % visSpacing == 0 ) +// { +// vtkDomainOutput->write( ); +// vtkSphereOutput->write( ); +// } + } + WALBERLA_MPI_BARRIER(); + timer.end(); + WALBERLA_LOG_INFO_ON_ROOT("runtime: " << timer.average()); + WALBERLA_LOG_INFO_ON_ROOT("*** SIMULATION - END ***"); + + WALBERLA_LOG_INFO_ON_ROOT("*** CHECKING RESULT - START ***"); + for (auto& currentBlock : *forest) + { + Storage * storage = currentBlock.getData< Storage >( storageID ); + BodyStorage& localStorage = (*storage)[0]; + + auto bodyIt = localStorage.begin(); + for (auto it = grid_generator::SCIterator(currentBlock.getAABB().getIntersection(generationDomain), Vector3<real_t>(spacing, spacing, spacing) * real_c(0.5), spacing); + it != grid_generator::SCIterator(); + ++it, ++bodyIt) + { + WALBERLA_CHECK_UNEQUAL(bodyIt, localStorage.end()); + WALBERLA_CHECK_FLOAT_EQUAL(bodyIt->getPosition(), *it); + } + } + WALBERLA_LOG_INFO_ON_ROOT("*** CHECKING RESULT - END ***"); + + return EXIT_SUCCESS; +} diff --git a/apps/benchmarks/PeriodicGranularGas/upload.py b/apps/benchmarks/PeriodicGranularGas/upload.py new file mode 100644 index 0000000000000000000000000000000000000000..799476c1d51d8d5a28a08c2a14b51c60df41f5ce --- /dev/null +++ b/apps/benchmarks/PeriodicGranularGas/upload.py @@ -0,0 +1,187 @@ +import os +import time +import math +import random +import re +from influxdb import InfluxDBClient +from git import Repo + + +def main(): + try: + write_user_pw = os.environ["INFLUXDB_WRITE_USER"] + except KeyError: + import sys + print('Password for the InfluxDB write_user was not set.\n', + 'See https://docs.gitlab.com/ee/ci/variables/#secret-variables', file=sys.stderr) + exc_info = sys.exc_info() + raise exc_info[0].with_traceback(exc_info[1], exc_info[2]) + + client = InfluxDBClient('i10grafana.informatik.uni-erlangen.de', 8086, + 'pe', write_user_pw, 'pe') + + #repo = Repo(search_parent_directories=True) + #commit = repo.head.commit + + with open("PeriodicGranularGas_DEM_NN.txt") as f: + s = f.read() + m = re.search('runtime: (\d*.\d*)', s) + + json_body = [ + { + 'measurement': 'pe_benchmark', + 'tags': { + 'host' : os.uname()[1], + 'image' : os.environ["DOCKER_IMAGE_NAME"], + 'model' : 'DEM', + 'friction': 'Coulomb', + 'sync' : 'next neighbor' + }, + 'time': int(time.time()), + 'fields': {'runtime': float(m.group(1))} + } + ] + print(float(m.group(1))) + client.write_points(json_body, time_precision='s') + + #************************************************* + + with open("PeriodicGranularGas_DEM_SO.txt") as f: + s = f.read() + m = re.search('runtime: (\d*.\d*)', s) + + json_body = [ + { + 'measurement': 'pe_benchmark', + 'tags': { + 'host' : os.uname()[1], + 'image' : os.environ["DOCKER_IMAGE_NAME"], + 'model' : 'DEM', + 'friction': 'Coulomb', + 'sync' : 'shadow owner' + }, + 'time': int(time.time()), + 'fields': {'runtime': float(m.group(1))} + } + ] + print(float(m.group(1))) + client.write_points(json_body, time_precision='s') + + #************************************************* + + with open("PeriodicGranularGas_HCSITS_NN_IFC.txt") as f: + s = f.read() + m = re.search('runtime: (\d*.\d*)', s) + + json_body = [ + { + 'measurement': 'pe_benchmark', + 'tags': { + 'host' : os.uname()[1], + 'image' : os.environ["DOCKER_IMAGE_NAME"], + 'model' : 'HCSITS', + 'friction': 'InelasticFrictionlessContact', + 'sync' : 'next neighbor' + }, + 'time': int(time.time()), + 'fields': {'runtime': float(m.group(1))} + } + ] + print(float(m.group(1))) + client.write_points(json_body, time_precision='s') + + #************************************************* + + with open("PeriodicGranularGas_HCSITS_NN_AICCBD.txt") as f: + s = f.read() + m = re.search('runtime: (\d*.\d*)', s) + + json_body = [ + { + 'measurement': 'pe_benchmark', + 'tags': { + 'host' : os.uname()[1], + 'image' : os.environ["DOCKER_IMAGE_NAME"], + 'model' : 'HCSITS', + 'friction': 'ApproximateInelasticCoulombContactByDecoupling', + 'sync' : 'next neighbor' + }, + 'time': int(time.time()), + 'fields': {'runtime': float(m.group(1))} + } + ] + print(float(m.group(1))) + client.write_points(json_body, time_precision='s') + + #************************************************* + + with open("PeriodicGranularGas_HCSITS_NN_ICCBD.txt") as f: + s = f.read() + m = re.search('runtime: (\d*.\d*)', s) + + json_body = [ + { + 'measurement': 'pe_benchmark', + 'tags': { + 'host' : os.uname()[1], + 'image' : os.environ["DOCKER_IMAGE_NAME"], + 'model' : 'HCSITS', + 'friction': 'InelasticCoulombContactByDecoupling', + 'sync' : 'next neighbor' + }, + 'time': int(time.time()), + 'fields': {'runtime': float(m.group(1))} + } + ] + print(float(m.group(1))) + client.write_points(json_body, time_precision='s') + + #************************************************* + + with open("PeriodicGranularGas_HCSITS_NN_IGMDC.txt") as f: + s = f.read() + m = re.search('runtime: (\d*.\d*)', s) + + json_body = [ + { + 'measurement': 'pe_benchmark', + 'tags': { + 'host' : os.uname()[1], + 'image' : os.environ["DOCKER_IMAGE_NAME"], + 'model' : 'HCSITS', + 'friction': 'InelasticGeneralizedMaximumDissipationContact', + 'sync' : 'next neighbor' + }, + 'time': int(time.time()), + 'fields': {'runtime': float(m.group(1))} + } + ] + print(float(m.group(1))) + client.write_points(json_body, time_precision='s') + + #************************************************* + + with open("PeriodicGranularGas_HCSITS_SO_IFC.txt") as f: + s = f.read() + m = re.search('runtime: (\d*.\d*)', s) + + json_body = [ + { + 'measurement': 'pe_benchmark', + 'tags': { + 'host' : os.uname()[1], + 'image' : os.environ["DOCKER_IMAGE_NAME"], + 'model' : 'HCSITS', + 'friction': 'InelasticFrictionlessContact', + 'sync' : 'shadow owner' + }, + 'time': int(time.time()), + 'fields': {'runtime': float(m.group(1))} + } + ] + print(float(m.group(1))) + client.write_points(json_body, time_precision='s') + + +if __name__ == "__main__": + main() diff --git a/apps/benchmarks/PoiseuilleChannel/PoiseuilleChannel.cpp b/apps/benchmarks/PoiseuilleChannel/PoiseuilleChannel.cpp index d19c5f3c8bb803e8fdde12b549b9c40311817da9..bba9184c57e791c44511ff9ca7895325c086f77e 100644 --- a/apps/benchmarks/PoiseuilleChannel/PoiseuilleChannel.cpp +++ b/apps/benchmarks/PoiseuilleChannel/PoiseuilleChannel.cpp @@ -88,12 +88,11 @@ #include "vtk/Initialization.h" #include "vtk/VTKOutput.h" -#include <boost/bind.hpp> - #include <algorithm> #include <cmath> #include <cstdlib> #include <cstring> +#include <functional> #include <iostream> #include <utility> #include <vector> @@ -303,7 +302,7 @@ static shared_ptr< SetupBlockForest > createSetupBlockForest( const blockforest: ( setup.zCells + uint_t(2) * FieldGhostLayers ) ) * memoryPerCell; forest->addRefinementSelectionFunction( refinementSelectionFunctions ); - forest->addWorkloadMemorySUIDAssignmentFunction( boost::bind( workloadAndMemoryAssignment, _1, memoryPerBlock ) ); + forest->addWorkloadMemorySUIDAssignmentFunction( std::bind( workloadAndMemoryAssignment, std::placeholders::_1, memoryPerBlock ) ); forest->init( AABB( real_c(0), real_c(0), real_c(0), real_c( setup.xBlocks * setup.xCells ), real_c( setup.yBlocks * setup.yCells ), @@ -847,12 +846,12 @@ void run( const shared_ptr< Config > & config, const LatticeModel_T & latticeMod // evaluation - const auto exactSolutionFunction = setup.circularProfile ? boost::bind( exactPipeVelocity, _1, blocks, setup ) : - boost::bind( exactPlatesVelocity, _1, blocks, setup ); + const auto exactSolutionFunction = setup.circularProfile ? std::bind( exactPipeVelocity, std::placeholders::_1, blocks, setup ) : + std::bind( exactPlatesVelocity, std::placeholders::_1, blocks, setup ); auto volumetricFlowRate = field::makeVolumetricFlowRateEvaluation< VelocityAdaptor_T, FlagField_T >( configBlock, blocks, velocityAdaptorId, flagFieldId, Fluid_Flag, - boost::bind( exactFlowRate, setup.flowRate_L ), + std::bind( exactFlowRate, setup.flowRate_L ), exactSolutionFunction ); volumetricFlowRate->setNormalizationFactor( real_t(1) / setup.maxVelocity_L ); volumetricFlowRate->setDomainNormalization( Vector3<real_t>( real_t(1) ) ); diff --git a/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp b/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp index ed907fc37b06df8e3e54691bebc52bc7ea7c495f..b7f9d2997a06c2fb7acca0d2c685fade0cdc4fd5 100644 --- a/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp +++ b/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp @@ -106,12 +106,12 @@ #include <boost/mpl/equal_to.hpp> #include <boost/mpl/int.hpp> #include <boost/mpl/or.hpp> -#include <boost/bind.hpp> #include <algorithm> #include <cmath> #include <cstdlib> #include <cstring> +#include <functional> #include <iostream> #include <utility> #include <vector> @@ -656,7 +656,7 @@ static shared_ptr< SetupBlockForest > createSetupBlockForest( const blockforest: ( setup.xCells + uint_t(2) * FieldGhostLayers ) ) * memoryPerCell; forest->addRefinementSelectionFunction( refinementSelectionFunctions ); - forest->addWorkloadMemorySUIDAssignmentFunction( boost::bind( workloadMemoryAndSUIDAssignment, _1, memoryPerBlock, boost::cref( setup ) ) ); + forest->addWorkloadMemorySUIDAssignmentFunction( std::bind( workloadMemoryAndSUIDAssignment, std::placeholders::_1, memoryPerBlock, std::cref( setup ) ) ); forest->init( AABB( real_c(0), real_c(0), real_c(0), setup.H * ( real_c(setup.xBlocks) * real_c(setup.xCells) ) / ( real_c(setup.yzBlocks) * real_c(setup.yzCells) ), setup.H, setup.H ), @@ -2602,7 +2602,8 @@ void run( const shared_ptr< Config > & config, const LatticeModel_T & latticeMod adaptiveRefinementLog = oss.str(); } - minTargetLevelDeterminationFunctions.add( boost::bind( keepInflowOutflowAtTheSameLevel, _1, _2, _3, boost::cref(setup) ) ); + minTargetLevelDeterminationFunctions.add( std::bind( keepInflowOutflowAtTheSameLevel, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::cref(setup) ) ); if( Is2D< LatticeModel_T >::value ) minTargetLevelDeterminationFunctions.add( pseudo2DTargetLevelCorrection ); @@ -3171,7 +3172,7 @@ int main( int argc, char **argv ) refinementSelectionFunctions.add( cylinderRefinementSelection ); } - refinementSelectionFunctions.add( boost::bind( setInflowOutflowToSameLevel, _1, setup ) ); + refinementSelectionFunctions.add( std::bind( setInflowOutflowToSameLevel, std::placeholders::_1, setup ) ); if( setup.pseudo2D ) refinementSelectionFunctions.add( Pseudo2DRefinementSelectionCorrection ); diff --git a/apps/showcases/BidisperseFluidizedBed/BidisperseFluidizedBedDPM.cpp b/apps/showcases/BidisperseFluidizedBed/BidisperseFluidizedBedDPM.cpp index de0512d8dd7e24c7ae85cf706293d63e28b2a368..b175c7c1d1810a0a6bd484949f745c7358b28201 100644 --- a/apps/showcases/BidisperseFluidizedBed/BidisperseFluidizedBedDPM.cpp +++ b/apps/showcases/BidisperseFluidizedBed/BidisperseFluidizedBedDPM.cpp @@ -889,7 +889,7 @@ int main( int argc, char **argv ) { // connect to pe const real_t overlap = real_t(1.5) * dx; - auto syncCall = boost::bind(pe::syncNextNeighbors<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), + auto syncCall = std::bind(pe::syncNextNeighbors<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree *>(NULL), overlap, false); shared_ptr<CollisionPropertiesEvaluator> collisionPropertiesEvaluator = walberla::make_shared<CollisionPropertiesEvaluator>(*cr); @@ -1196,7 +1196,7 @@ int main( int argc, char **argv ) { velocityFieldID, svfFieldID, pressureGradientFieldID, dragCorrelationFunction, viscosity); - dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if (dist == Distribution::DKernel) { typedef pe_coupling::discrete_particle_methods::InteractionForceEvaluator<FlagField_T, field::NearestNeighborFieldInterpolator, field::KernelDistributor> IFE_T; shared_ptr<IFE_T> forceEvaluatorPtr = make_shared<IFE_T>(blocks, dragForceFieldID, bodyStorageID, @@ -1204,7 +1204,7 @@ int main( int argc, char **argv ) { velocityFieldID, svfFieldID, pressureGradientFieldID, dragCorrelationFunction, viscosity); - dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } else if (interpol == Interpolation::IKernel) { if (dist == Distribution::DNearestNeighbor) { @@ -1214,7 +1214,7 @@ int main( int argc, char **argv ) { velocityFieldID, svfFieldID, pressureGradientFieldID, dragCorrelationFunction, viscosity); - dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if (dist == Distribution::DKernel) { typedef pe_coupling::discrete_particle_methods::InteractionForceEvaluator<FlagField_T, field::KernelFieldInterpolator, field::KernelDistributor> IFE_T; shared_ptr<IFE_T> forceEvaluatorPtr = make_shared<IFE_T>(blocks, dragForceFieldID, bodyStorageID, @@ -1222,7 +1222,7 @@ int main( int argc, char **argv ) { velocityFieldID, svfFieldID, pressureGradientFieldID, dragCorrelationFunction, viscosity); - dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } else if (interpol == Interpolation::ITrilinear) { if (dist == Distribution::DNearestNeighbor) { @@ -1232,7 +1232,7 @@ int main( int argc, char **argv ) { velocityFieldID, svfFieldID, pressureGradientFieldID, dragCorrelationFunction, viscosity); - dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if (dist == Distribution::DKernel) { typedef pe_coupling::discrete_particle_methods::InteractionForceEvaluator<FlagField_T, field::TrilinearFieldInterpolator, field::KernelDistributor> IFE_T; shared_ptr<IFE_T> forceEvaluatorPtr = make_shared<IFE_T>(blocks, dragForceFieldID, bodyStorageID, @@ -1240,7 +1240,7 @@ int main( int argc, char **argv ) { velocityFieldID, svfFieldID, pressureGradientFieldID, dragCorrelationFunction, viscosity); - dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } } @@ -1260,7 +1260,7 @@ int main( int argc, char **argv ) { shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, velocityFieldID, velocityCurlFieldID, liftCorrelationFunction, viscosity ); - liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if( dist == Distribution::DKernel ) { @@ -1268,7 +1268,7 @@ int main( int argc, char **argv ) { shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, velocityFieldID, velocityCurlFieldID, liftCorrelationFunction, viscosity ); - liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } else if( interpol == Interpolation::IKernel ) @@ -1279,7 +1279,7 @@ int main( int argc, char **argv ) { shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, velocityFieldID, velocityCurlFieldID, liftCorrelationFunction, viscosity ); - liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if( dist == Distribution::DKernel ) { @@ -1287,7 +1287,7 @@ int main( int argc, char **argv ) { shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, velocityFieldID, velocityCurlFieldID, liftCorrelationFunction, viscosity ); - liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } else if( interpol == Interpolation::ITrilinear ) @@ -1298,7 +1298,7 @@ int main( int argc, char **argv ) { shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, velocityFieldID, velocityCurlFieldID, liftCorrelationFunction, viscosity ); - liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if( dist == Distribution::DKernel ) { @@ -1306,7 +1306,7 @@ int main( int argc, char **argv ) { shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, velocityFieldID, velocityCurlFieldID, liftCorrelationFunction, viscosity ); - liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } @@ -1320,7 +1320,7 @@ int main( int argc, char **argv ) { shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, timeDerivativeVelocityFieldID, addedMassCorrelationFunction, bodyVelocityTimeDerivativeEvaluator ); - addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if( dist == Distribution::DKernel ) { @@ -1328,7 +1328,7 @@ int main( int argc, char **argv ) { shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, timeDerivativeVelocityFieldID, addedMassCorrelationFunction, bodyVelocityTimeDerivativeEvaluator ); - addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } else if( interpol == Interpolation::IKernel ) @@ -1339,7 +1339,7 @@ int main( int argc, char **argv ) { shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, timeDerivativeVelocityFieldID, addedMassCorrelationFunction, bodyVelocityTimeDerivativeEvaluator ); - addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if( dist == Distribution::DKernel ) { @@ -1347,7 +1347,7 @@ int main( int argc, char **argv ) { shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, timeDerivativeVelocityFieldID, addedMassCorrelationFunction, bodyVelocityTimeDerivativeEvaluator ); - addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } else if( interpol == Interpolation::ITrilinear ) @@ -1358,7 +1358,7 @@ int main( int argc, char **argv ) { shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, timeDerivativeVelocityFieldID, addedMassCorrelationFunction, bodyVelocityTimeDerivativeEvaluator ); - addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if( dist == Distribution::DKernel ) { @@ -1366,7 +1366,7 @@ int main( int argc, char **argv ) { shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, timeDerivativeVelocityFieldID, addedMassCorrelationFunction, bodyVelocityTimeDerivativeEvaluator ); - addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } @@ -1376,7 +1376,7 @@ int main( int argc, char **argv ) { { typedef pe_coupling::discrete_particle_methods::LubricationForceEvaluator LE_T; shared_ptr<LE_T> lubEval = make_shared<LE_T>( blocks, globalBodyStorage, bodyStorageID, viscosity, lubricationCutOffDistance ); - lubricationEvaluationFunction = boost::bind(&LE_T::operator(), lubEval); + lubricationEvaluationFunction = std::bind(&LE_T::operator(), lubEval); } else { diff --git a/apps/tutorials/basics/02_Sweeps.cpp b/apps/tutorials/basics/02_Sweeps.cpp index 03ef87b5efb2d6a099c0919a8d87a44bd6ea3f0c..95c0cf1abc238e0015c9d2cc7fd175946e8894bc 100644 --- a/apps/tutorials/basics/02_Sweeps.cpp +++ b/apps/tutorials/basics/02_Sweeps.cpp @@ -24,7 +24,7 @@ #include "gui/Gui.h" #include "timeloop/SweepTimeloop.h" -#include <boost/bind.hpp> +#include <functional> using namespace walberla; @@ -125,7 +125,7 @@ int main( int argc, char ** argv ) // registering the function sweep auto pointerToTwoArgFunction = & simpleSweep; - auto pointerToOneArgFunction = boost::bind( pointerToTwoArgFunction, _1, fieldID ); + auto pointerToOneArgFunction = std::bind( pointerToTwoArgFunction, std::placeholders::_1, fieldID ); timeloop.add() << Sweep( pointerToOneArgFunction, "BogusAlgorithm" ); // registering the class sweep diff --git a/apps/tutorials/pe/02_ConfinedGasExtended.cpp b/apps/tutorials/pe/02_ConfinedGasExtended.cpp index b5ac5193e8d090e2834a47514d037109b662781b..f0e4edc205c368ad609c2683a652defcadc8f5f7 100644 --- a/apps/tutorials/pe/02_ConfinedGasExtended.cpp +++ b/apps/tutorials/pe/02_ConfinedGasExtended.cpp @@ -33,6 +33,8 @@ #include <postprocessing/sqlite/SQLite.h> #include <vtk/VTKOutput.h> +#include <functional> + using namespace walberla; using namespace walberla::pe; using namespace walberla::timing; @@ -152,20 +154,20 @@ int main( int argc, char ** argv ) std::function<void(void)> syncCall; if (!syncShadowOwners) { - syncCall = boost::bind( pe::syncNextNeighbors<BodyTuple>, boost::ref(*forest), storageID, &tt, real_c(0.0), false ); + syncCall = std::bind( pe::syncNextNeighbors<BodyTuple>, std::ref(*forest), storageID, &tt, real_c(0.0), false ); } else { - syncCall = boost::bind( pe::syncShadowOwners<BodyTuple>, boost::ref(*forest), storageID, &tt, real_c(0.0), false ); + syncCall = std::bind( pe::syncShadowOwners<BodyTuple>, std::ref(*forest), storageID, &tt, real_c(0.0), false ); } //! [Bind Sync Call] std::function<void(void)> syncCallWithoutTT; if (!syncShadowOwners) { - syncCallWithoutTT = boost::bind( pe::syncNextNeighbors<BodyTuple>, boost::ref(*forest), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false ); + syncCallWithoutTT = std::bind( pe::syncNextNeighbors<BodyTuple>, std::ref(*forest), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false ); } else { - syncCallWithoutTT = boost::bind( pe::syncShadowOwners<BodyTuple>, boost::ref(*forest), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false ); + syncCallWithoutTT = std::bind( pe::syncShadowOwners<BodyTuple>, std::ref(*forest), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false ); } //! [Bind Sync Call] diff --git a/cmake/waLBerlaFunctions.cmake b/cmake/waLBerlaFunctions.cmake index d4b9a01f587732b6dbe8dce3e55092a3913c2125..196d3f4777ad4b4efd6d688f5c99361c107ef2a6 100644 --- a/cmake/waLBerlaFunctions.cmake +++ b/cmake/waLBerlaFunctions.cmake @@ -1,30 +1,29 @@ - include ( waLBerlaHelperFunctions ) include ( waLBerlaModuleDependencySystem ) set ( WALBERLA_GLOB_FILES *.cpp - *.c - *.h - *.cu + *.c + *.h + *.cu CACHE INTERNAL "File endings to glob for source files" ) ####################################################################################################################### # # Creates a walberla module library -# +# # # Keywords: # DEPENDS [required] list of modules, that this module depends on # FILES [optional] list of all source and header files belonging to that module # if this is not given, all source and header files in the directory are added. # Careful: when file was added or deleted, cmake has to be run again -# EXCLUDE [optional] Files that should not be included in the module (but are located in module directory). +# EXCLUDE [optional] Files that should not be included in the module (but are located in module directory). # This makes only sense if FILES was not specified, and all files have been added automatically. # BUILD_ONLY_IF_FOUND Before building the module test if all libraries specified here are availbable. # [optional] This is done using the ${arg}_FOUND variable. -# Example: waLBerla_add_module( DEPENDS someModule BUILD_ONLY_IF_FOUND pe) +# Example: waLBerla_add_module( DEPENDS someModule BUILD_ONLY_IF_FOUND pe) # This module is only built if PE_FOUND is true. # ####################################################################################################################### @@ -34,11 +33,11 @@ function ( waLBerla_add_module ) set( oneValueArgs ) set( multiValueArgs DEPENDS EXCLUDE FILES BUILD_ONLY_IF_FOUND ) cmake_parse_arguments( ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) - + # Module name is the directory relative to WALBERLA_MODULE_DIRS get_current_module_name ( moduleName ) get_module_library_name ( moduleLibraryName ${moduleName} ) - + # Test if all required libraries are available # this is detected using the _FOUND variable foreach ( externalName ${ARG_BUILD_ONLY_IF_FOUND} ) @@ -49,7 +48,7 @@ function ( waLBerla_add_module ) endif() endforeach() - # Take source files either from parameter or search all source files + # Take source files either from parameter or search all source files file ( GLOB_RECURSE allFiles "*" ) # Find all files if ( ARG_FILES ) foreach( sourceFile ${ARG_FILES} ) @@ -60,7 +59,7 @@ function ( waLBerla_add_module ) file ( GLOB_RECURSE sourceFiles ${WALBERLA_GLOB_FILES} ) # Find all source files endif() - # Remove exclude files from the sources + # Remove exclude files from the sources if ( ARG_EXCLUDE ) foreach ( fileToExclude ${ARG_EXCLUDE} ) get_filename_component( fileToExclude ${fileToExclude} ABSOLUTE ) @@ -77,17 +76,17 @@ function ( waLBerla_add_module ) endif ( ) # Dependency Check - check_dependencies( missingDeps additionalDeps FILES ${sourceFiles} EXPECTED_DEPS ${ARG_DEPENDS} ${moduleName} ) + check_dependencies( missingDeps additionalDeps FILES ${sourceFiles} EXPECTED_DEPS ${ARG_DEPENDS} ${moduleName} ) if ( missingDeps ) message ( WARNING "The module ${moduleName} depends on ${missingDeps} which are not listed as dependencies!" ) endif() - set( hasSourceFiles FALSE ) - foreach ( sourceFile ${sourceFiles} ) + set( hasSourceFiles FALSE ) + foreach ( sourceFile ${sourceFiles} ) if ( ${sourceFile} MATCHES "\\.(c|cpp|cu)" ) - set( hasSourceFiles TRUE ) - endif( ) - endforeach( ) + set( hasSourceFiles TRUE ) + endif( ) + endforeach( ) if ( hasSourceFiles ) set( generatedSourceFiles ) @@ -103,11 +102,11 @@ function ( waLBerla_add_module ) else() add_library( ${moduleLibraryName} STATIC ${sourceFiles} ${generatedSourceFiles} ${generatorSourceFiles} ${otherFiles} ) endif( CUDA_FOUND ) - + set_source_files_properties( ${generatedSourceFiles} PROPERTIES GENERATED TRUE ) - else( ) - add_custom_target( ${moduleLibraryName} SOURCES ${sourceFiles} ${generatedSourceFiles} ${otherFiles} ) # dummy IDE target - endif( ) + else( ) + add_custom_target( ${moduleLibraryName} SOURCES ${sourceFiles} ${generatedSourceFiles} ${otherFiles} ) # dummy IDE target + endif( ) waLBerla_register_dependency ( ${moduleName} ${ARG_DEPENDS} ) @@ -117,36 +116,36 @@ function ( waLBerla_add_module ) if( WALBERLA_GROUP_PROJECTS ) set_property( TARGET ${moduleLibraryName} PROPERTY FOLDER "SRC" ) endif() - + # Install rule for library get_target_property( module_type ${moduleLibraryName} TYPE ) - if( ${module_type} MATCHES LIBRARY ) + if( ${module_type} MATCHES LIBRARY ) install ( TARGETS ${moduleLibraryName} RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib ) endif( ) - + # Install rule for header - install ( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ - DESTINATION "walberla/${moduleName}" + install ( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ + DESTINATION "walberla/${moduleName}" FILES_MATCHING PATTERN "*.h" - PATTERN "*.in.h" EXCLUDE + PATTERN "*.in.h" EXCLUDE PATTERN "CMakeFiles" EXCLUDE ) - - # Install generated headers if necessary - if ( NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR} ) - install ( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ - DESTINATION "walberla/${moduleName}" + + # Install generated headers if necessary + if ( NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR} ) + install ( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ + DESTINATION "walberla/${moduleName}" FILES_MATCHING PATTERN "*.h" - PATTERN "*.in.h" EXCLUDE + PATTERN "*.in.h" EXCLUDE PATTERN "CMakeFiles" EXCLUDE ) - endif() - - + endif() + + # Report module statistics - which is later on written out to a json file # This file is used in the doxygen documentation to display a module graph #waLBerla_module_statistics ( FILES ${sourceFiles} DEPENDS ${ARG_DEPENDS} ) - + endfunction ( waLBerla_add_module ) ####################################################################################################################### @@ -160,7 +159,7 @@ endfunction ( waLBerla_add_module ) # The application is linked against all waLBerla modules that are listed after DEPENDS # # -# NAME [required] Name of application +# NAME [required] Name of application # GROUP [optional] IDE group name (e.g. VS) # DEPENDS [required] list of modules, that this application depends on # FILES [optional] list of all source and header files belonging to that application @@ -178,9 +177,9 @@ function ( waLBerla_add_executable ) cmake_parse_arguments( ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) if( NOT ARG_NAME ) - message ( FATAL_ERROR "waLBerla_add_executable called without a NAME" ) + message ( FATAL_ERROR "waLBerla_add_executable called without a NAME" ) endif() - + # Skip this app, if it depends on modules that have not been built ( because they for example depend on PE) foreach ( depMod ${ARG_DEPENDS} ) get_module_library_name ( depModLibraryName ${depMod} ) @@ -189,8 +188,8 @@ function ( waLBerla_add_executable ) return() endif() endforeach() - - # Take source files either from parameter or search all source files + + # Take source files either from parameter or search all source files set( sourceFiles ) if ( ARG_FILES ) foreach( sourceFile ${ARG_FILES} ) @@ -218,14 +217,14 @@ function ( waLBerla_add_executable ) message(STATUS "Skipping ${ARG_NAME} since pystencils code generation is not enabled") return() endif() - + if ( CUDA_FOUND ) cuda_add_executable( ${ARG_NAME} ${sourceFiles} ${generatedSourceFiles} ${generatorSourceFiles} ) else() add_executable( ${ARG_NAME} ${sourceFiles} ${generatedSourceFiles} ${generatorSourceFiles} ) endif() - + set_source_files_properties( ${generatedSourceFiles} PROPERTIES GENERATED TRUE ) target_link_modules ( ${ARG_NAME} ${ARG_DEPENDS} ) @@ -238,7 +237,7 @@ function ( waLBerla_add_executable ) endif() set_property( TARGET ${ARG_NAME} PROPERTY FOLDER ${ARG_GROUP} ) endif() - + endfunction ( waLBerla_add_executable ) ####################################################################################################################### @@ -257,20 +256,20 @@ function ( waLBerla_compile_test ) set( oneValueArgs NAME ) set( multiValueArgs FILES DEPENDS ) cmake_parse_arguments( ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) - + # Module name is the directory relative to WALBERLA_MODULE_DIRS get_current_module_name ( moduleName ) - + # Filename of first source file is used as name for testcase if no name was given if( NOT ARG_NAME ) list( GET ARG_FILES 0 ARG_NAME ) get_filename_component( ARG_NAME ${ARG_NAME} NAME_WE ) endif() - - waLBerla_add_executable ( NAME ${ARG_NAME} GROUP "TESTS/${moduleName}" + + waLBerla_add_executable ( NAME ${ARG_NAME} GROUP "TESTS/${moduleName}" DEPENDS ${ARG_DEPENDS} ${moduleName} FILES ${ARG_FILES} ) - - + + endfunction ( waLBerla_compile_test ) ####################################################################################################################### @@ -280,9 +279,9 @@ endfunction ( waLBerla_compile_test ) ####################################################################################################################### # # Links all files in current source dir matching a globbing expression to the build directory -# +# # first parameter is glob expression -# +# # Typical usage: link all parameter files in same folder as the binary was produced # Assuming the parameter files end with prm, write this to your CMakeLists in the # app or test folder: @@ -293,15 +292,15 @@ endfunction ( waLBerla_compile_test ) ####################################################################################################################### function ( waLBerla_link_files_to_builddir globExpression ) - + # don't need links for in-source builds if( CMAKE_CURRENT_SOURCE_DIR STREQUAL "${CMAKE_CURRENT_BINARY_DIR}" ) return() endif() - + file( GLOB filesToLink RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${globExpression} ) - - foreach( f ${filesToLink} ) + + foreach( f ${filesToLink} ) if( CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows" ) configure_file( ${f} ${f} COPYONLY ) else() @@ -309,9 +308,9 @@ function ( waLBerla_link_files_to_builddir globExpression ) ${CMAKE_CURRENT_SOURCE_DIR}/${f} ${CMAKE_CURRENT_BINARY_DIR}/${f} ) endif() - + endforeach() - + endfunction ( waLBerla_link_files_to_builddir ) @@ -319,37 +318,37 @@ endfunction ( waLBerla_link_files_to_builddir ) ####################################################################################################################### # -# Adds an executable to CTest. -# +# Adds an executable to CTest. +# # Wrapper around add_test, that handles test labels and parallel runs # Adds the module name as test label, plus optional user defined labels. # # NAME [required] Name of test -# PROCESSES [optional] Number of MPI processes, that are used to start this test. +# PROCESSES [optional] Number of MPI processes, that are used to start this test. # If walberla is built without MPI, and PROCESSES > 1, the test is not added # Defaults to 1 # COMMAND [optional] The command that is executed. Use this to start with parameter files or other -# command line options. +# command line options. # Defaults to $<TARGET_FILE:${NAME}> (for this syntax see cmake documentation of add_test ) -# LABELS [optional] Additional test labels. +# LABELS [optional] Additional test labels. # ####################################################################################################################### function ( waLBerla_execute_test ) - + set( options NO_MODULE_LABEL ) set( oneValueArgs NAME PROCESSES ) set( multiValueArgs COMMAND LABELS CONFIGURATIONS DEPENDS_ON_TARGETS ) cmake_parse_arguments( ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) if( NOT ARG_NAME ) - message ( FATAL_ERROR "waLBerla_execute_test called without a NAME" ) + message ( FATAL_ERROR "waLBerla_execute_test called without a NAME" ) endif() - + if( NOT ARG_COMMAND AND NOT TARGET ${ARG_NAME} ) message ( STATUS "Skipping test ${ARG_NAME} since the corresponding target is not built" ) return() - endif() + endif() foreach( dependency_target ${ARG_DEPENDS_ON_TARGETS} ) if( NOT TARGET ${dependency_target} ) @@ -357,7 +356,7 @@ function ( waLBerla_execute_test ) return() endif() endforeach( dependency_target ) - + if( NOT ARG_PROCESSES ) set ( numProcesses 1 ) else() @@ -369,27 +368,28 @@ function ( waLBerla_execute_test ) endif() if( WALBERLA_BUILD_WITH_MPI ) - list( INSERT ARG_COMMAND 0 ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${numProcesses} ${MPIEXEC_PREFLAGS} ) + if( CMAKE_VERSION VERSION_LESS 3.10.0 ) + set ( MPIEXEC_EXECUTABLE ${MPIEXEC} ) + endif() + list( INSERT ARG_COMMAND 0 ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${numProcesses} ${MPIEXEC_PREFLAGS} ) elseif( numProcesses GREATER 1 ) return() - endif() - + endif() + if( ARG_CONFIGURATIONS ) add_test( NAME ${ARG_NAME} ${ARG_UNPARSED_ARGUMENTS} COMMAND ${ARG_COMMAND} CONFIGURATIONS ${ARG_CONFIGURATIONS} ) else() add_test( NAME ${ARG_NAME} ${ARG_UNPARSED_ARGUMENTS} COMMAND ${ARG_COMMAND} ) endif() - + if( ARG_NO_MODULE_LABEL ) set_tests_properties ( ${ARG_NAME} PROPERTIES LABELS "${ARG_LABELS}" ) else() - get_current_module_name ( moduleName ) + get_current_module_name ( moduleName ) set_tests_properties ( ${ARG_NAME} PROPERTIES LABELS "${moduleName} ${ARG_LABELS}" ) endif() set_tests_properties ( ${ARG_NAME} PROPERTIES PROCESSORS ${numProcesses} ) - + endfunction ( waLBerla_execute_test ) ####################################################################################################################### - - diff --git a/src/blockforest/BlockNeighborhoodSection.h b/src/blockforest/BlockNeighborhoodSection.h index f39b5d1f2029ceed24aff5b79fcabd389ee6d1be..161e2f2e41ee782cbad25de3cea39b400b345847 100644 --- a/src/blockforest/BlockNeighborhoodSection.h +++ b/src/blockforest/BlockNeighborhoodSection.h @@ -25,7 +25,7 @@ #include "core/debug/Debug.h" #include "stencil/Directions.h" - +#include <array> namespace walberla { namespace blockforest { @@ -94,31 +94,28 @@ inline uint_t getBlockMaxNeighborhoodSectionSize( const uint_t sectionIndex ) -inline const uint_t * getFaceNeighborhoodSectionIndices() +inline const std::array<uint_t, 6> & getFaceNeighborhoodSectionIndices() { - static const uint_t faces[] = { uint_t(4), uint_t(10), uint_t(12), uint_t(13), uint_t(15), uint_t(21) }; + static std::array<uint_t, 6> faces{ { uint_t(4), uint_t(10), uint_t(12), uint_t(13), uint_t(15), uint_t(21) } }; return faces; } - -inline const uint_t * getEdgeNeighborhoodSectionIndices() +inline const std::array<uint_t,12> & getEdgeNeighborhoodSectionIndices() { - static const uint_t edges[] = { uint_t( 1), uint_t( 3), uint_t( 5), uint_t( 7), uint_t( 9), uint_t(11), - uint_t(14), uint_t(16), uint_t(18), uint_t(20), uint_t(22), uint_t(24) }; + static std::array<uint_t,12> edges{{ uint_t( 1), uint_t( 3), uint_t( 5), uint_t( 7), uint_t( 9), uint_t(11), + uint_t(14), uint_t(16), uint_t(18), uint_t(20), uint_t(22), uint_t(24) }}; return edges; } - -inline const uint_t * getCornerNeighborhoodSectionIndices() +inline const std::array<uint_t, 8> & getCornerNeighborhoodSectionIndices() { - static const uint_t corners[] = { uint_t( 0), uint_t( 2), uint_t( 6), uint_t( 8), - uint_t(17), uint_t(19), uint_t(23), uint_t(25) }; + static std::array<uint_t, 8> corners {{ uint_t( 0), uint_t( 2), uint_t( 6), uint_t( 8), + uint_t(17), uint_t(19), uint_t(23), uint_t(25) }}; return corners; } - } // namespace blockforest } // namespace walberla diff --git a/src/blockforest/Initialization.cpp b/src/blockforest/Initialization.cpp index 8704ae5f02d045a560c50f3b493f1419409147ed..dea96fed6a823ed0a910c4d12b30b18a736fe63a 100644 --- a/src/blockforest/Initialization.cpp +++ b/src/blockforest/Initialization.cpp @@ -31,6 +31,8 @@ #include "stencil/D3Q19.h" +#include <functional> + namespace walberla { namespace blockforest { @@ -500,7 +502,7 @@ createUniformBlockGrid( const AABB& domainAABB, numeric_cast< memory_t >( maxBlocksPerProcess ); GlobalLoadBalancing::MetisConfiguration< SetupBlock > metisConfig( includeMetis, forceMetis, - boost::bind( cellWeightedCommunicationCost,_1,_2, + std::bind( cellWeightedCommunicationCost, std::placeholders::_1, std::placeholders::_2, numberOfXCellsPerBlock, numberOfYCellsPerBlock, numberOfZCellsPerBlock ) ); diff --git a/src/blockforest/SetupBlockForest.cpp b/src/blockforest/SetupBlockForest.cpp index 9ae11ce9cb13d6b669c3792acde13e74ae02199f..3c4b40652e59ffcba3e0a383a3178aff509aba8a 100644 --- a/src/blockforest/SetupBlockForest.cpp +++ b/src/blockforest/SetupBlockForest.cpp @@ -546,7 +546,7 @@ void SetupBlockForest::getBlocks( std::vector< SetupBlock* >& blocks, const uint void SetupBlockForest::mapPointToPeriodicDomain( real_t & px, real_t & py, real_t & pz ) const { - boost::array< bool, 3 > periodic; + std::array< bool, 3 > periodic; periodic[0] = periodic_[0]; periodic[1] = periodic_[1]; periodic[2] = periodic_[2]; diff --git a/src/blockforest/StructuredBlockForest.h b/src/blockforest/StructuredBlockForest.h index 82f4e810d1444d18ebbb1f47e9cd19a42d2ab2c2..ac021fe66acce0eb8a24fa662b625ad906170762 100644 --- a/src/blockforest/StructuredBlockForest.h +++ b/src/blockforest/StructuredBlockForest.h @@ -24,6 +24,7 @@ #include "BlockForest.h" #include "domain_decomposition/StructuredBlockStorage.h" +#include <functional> namespace walberla { namespace blockforest { @@ -205,7 +206,7 @@ inline StructuredBlockForest::StructuredBlockForest( const shared_ptr< BlockFore blockForest_( blockForest ) { blockForest_->addRefreshCallbackFunctionBeforeBlockDataIsUnpacked( - BlockForest::RefreshCallbackWrappper( boost::bind( resetCellDecompositionInStorage, boost::ref(*this) ) ) ); + BlockForest::RefreshCallbackWrappper( std::bind( resetCellDecompositionInStorage, std::ref(*this) ) ) ); blockCells_[0] = blockXCells; blockCells_[1] = blockYCells; diff --git a/src/blockforest/communication/NonUniformBufferedScheme.h b/src/blockforest/communication/NonUniformBufferedScheme.h index e2eca543d736d543748d115ee645f91b12323e01..3e206f36d1aa4bfca2eebf14859dd22b68da72bd 100644 --- a/src/blockforest/communication/NonUniformBufferedScheme.h +++ b/src/blockforest/communication/NonUniformBufferedScheme.h @@ -36,10 +36,9 @@ #include "core/selectable/IsSetSelected.h" #include "core/uid/SUID.h" -#include <boost/bind.hpp> -#include <functional> #include <map> +#include <functional> #include <set> #include <vector> @@ -110,7 +109,7 @@ public: //@{ void startCommunication() { startCommunicateEqualLevel(); startCommunicateCoarseToFine(); startCommunicateFineToCoarse(); } - std::function<void()> getStartCommunicateFunctor() { return boost::bind( &NonUniformBufferedScheme::startCommunication, this ); } + std::function<void()> getStartCommunicateFunctor() { return std::bind( &NonUniformBufferedScheme::startCommunication, this ); } inline void startCommunicateEqualLevel(); inline void startCommunicateCoarseToFine(); @@ -121,7 +120,7 @@ public: inline void startCommunicateFineToCoarse( const uint_t fineLevel ); void wait() { waitCommunicateEqualLevel(); waitCommunicateCoarseToFine(); waitCommunicateFineToCoarse(); } - std::function<void() > getWaitFunctor() { return boost::bind( &NonUniformBufferedScheme::wait, this ); } + std::function<void() > getWaitFunctor() { return std::bind( &NonUniformBufferedScheme::wait, this ); } inline void waitCommunicateEqualLevel(); inline void waitCommunicateCoarseToFine(); @@ -659,13 +658,13 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationEqualLevel( const uint localBuffers.push_back( buffer ); const uint_t bufferIndex = uint_c( localBuffers.size() ) - uint_t(1); - VoidFunction pack = boost::bind( &NonUniformBufferedScheme<Stencil>::localBufferPacking, this, - EQUAL_LEVEL, index, bufferIndex, boost::cref( *packInfo ), block, neighbor, *dir ); + VoidFunction pack = std::bind( &NonUniformBufferedScheme<Stencil>::localBufferPacking, this, + EQUAL_LEVEL, index, bufferIndex, std::cref( *packInfo ), block, neighbor, *dir ); threadsafeLocalCommunication.push_back( pack ); - VoidFunction unpack = boost::bind( &NonUniformBufferedScheme<Stencil>::localBufferUnpacking, this, - EQUAL_LEVEL, index, bufferIndex, boost::cref( *packInfo ), neighbor, block, *dir ); + VoidFunction unpack = std::bind( &NonUniformBufferedScheme<Stencil>::localBufferUnpacking, this, + EQUAL_LEVEL, index, bufferIndex, std::cref( *packInfo ), neighbor, block, *dir ); if( (*packInfo)->threadsafeReceiving() ) threadsafeLocalCommunicationUnpack.push_back( unpack ); @@ -674,7 +673,7 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationEqualLevel( const uint } else { - VoidFunction localCommunicationFunction = boost::bind( &blockforest::communication::NonUniformPackInfo::communicateLocalEqualLevel, + VoidFunction localCommunicationFunction = std::bind( &blockforest::communication::NonUniformPackInfo::communicateLocalEqualLevel, *packInfo, block, neighbor, *dir ); if( (*packInfo)->threadsafeReceiving() ) threadsafeLocalCommunication.push_back( localCommunicationFunction ); @@ -688,10 +687,10 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationEqualLevel( const uint auto nProcess = block->getNeighborProcess( neighborIdx, uint_t(0) ); if( !packInfos_.empty() ) - sendFunctions[ nProcess ].push_back( boost::bind( NonUniformBufferedScheme<Stencil>::writeHeader, _1, block->getId(), receiverId, *dir ) ); + sendFunctions[ nProcess ].push_back( std::bind( NonUniformBufferedScheme<Stencil>::writeHeader, std::placeholders::_1, block->getId(), receiverId, *dir ) ); for( auto packInfo = packInfos_.begin(); packInfo != packInfos_.end(); ++packInfo ) - sendFunctions[ nProcess ].push_back( boost::bind( &blockforest::communication::NonUniformPackInfo::packDataEqualLevel, *packInfo, block, *dir, _1 ) ); + sendFunctions[ nProcess ].push_back( std::bind( &blockforest::communication::NonUniformPackInfo::packDataEqualLevel, *packInfo, block, *dir, std::placeholders::_1 ) ); } } } @@ -700,8 +699,8 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationEqualLevel( const uint for( auto sender = sendFunctions.begin(); sender != sendFunctions.end(); ++sender ) { - bufferSystem->addSendingFunction ( int_c(sender->first), boost::bind( NonUniformBufferedScheme<Stencil>::send, _1, sender->second ) ); - bufferSystem->addReceivingFunction( int_c(sender->first), boost::bind( &NonUniformBufferedScheme<Stencil>::receive, this, _1 ) ); + bufferSystem->addSendingFunction ( int_c(sender->first), std::bind( NonUniformBufferedScheme<Stencil>::send, std::placeholders::_1, sender->second ) ); + bufferSystem->addReceivingFunction( int_c(sender->first), std::bind( &NonUniformBufferedScheme<Stencil>::receive, this, std::placeholders::_1 ) ); } setupBeforeNextCommunication = char(0); @@ -785,13 +784,13 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationCoarseToFine( const ui localBuffers.push_back( buffer ); const uint_t bufferIndex = uint_c( localBuffers.size() ) - uint_t(1); - VoidFunction pack = boost::bind( &NonUniformBufferedScheme<Stencil>::localBufferPacking, this, - COARSE_TO_FINE, index, bufferIndex, boost::cref( *packInfo ), block, neighbor, *dir ); + VoidFunction pack = std::bind( &NonUniformBufferedScheme<Stencil>::localBufferPacking, this, + COARSE_TO_FINE, index, bufferIndex, std::cref( *packInfo ), block, neighbor, *dir ); threadsafeLocalCommunication.push_back( pack ); - VoidFunction unpack = boost::bind( &NonUniformBufferedScheme<Stencil>::localBufferUnpacking, this, - COARSE_TO_FINE, index, bufferIndex, boost::cref( *packInfo ), neighbor, block, *dir ); + VoidFunction unpack = std::bind( &NonUniformBufferedScheme<Stencil>::localBufferUnpacking, this, + COARSE_TO_FINE, index, bufferIndex, std::cref( *packInfo ), neighbor, block, *dir ); if( (*packInfo)->threadsafeReceiving() ) threadsafeLocalCommunicationUnpack.push_back( unpack ); @@ -800,7 +799,7 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationCoarseToFine( const ui } else { - VoidFunction localCommunicationFunction = boost::bind( &blockforest::communication::NonUniformPackInfo::communicateLocalCoarseToFine, + VoidFunction localCommunicationFunction = std::bind( &blockforest::communication::NonUniformPackInfo::communicateLocalCoarseToFine, *packInfo, block, neighbor, *dir ); if( (*packInfo)->threadsafeReceiving() ) threadsafeLocalCommunication.push_back( localCommunicationFunction ); @@ -814,10 +813,10 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationCoarseToFine( const ui auto nProcess = block->getNeighborProcess( neighborIdx, n ); if( !packInfos_.empty() ) - sendFunctions[ nProcess ].push_back( boost::bind( NonUniformBufferedScheme<Stencil>::writeHeader, _1, block->getId(), receiverId, *dir ) ); + sendFunctions[ nProcess ].push_back( std::bind( NonUniformBufferedScheme<Stencil>::writeHeader, std::placeholders::_1, block->getId(), receiverId, *dir ) ); for( auto packInfo = packInfos_.begin(); packInfo != packInfos_.end(); ++packInfo ) - sendFunctions[ nProcess ].push_back( boost::bind( &blockforest::communication::NonUniformPackInfo::packDataCoarseToFine, *packInfo, block, receiverId, *dir, _1 ) ); + sendFunctions[ nProcess ].push_back( std::bind( &blockforest::communication::NonUniformPackInfo::packDataCoarseToFine, *packInfo, block, receiverId, *dir, std::placeholders::_1 ) ); } } } @@ -844,10 +843,10 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationCoarseToFine( const ui resetBufferSystem( bufferSystem ); for( auto sender = sendFunctions.begin(); sender != sendFunctions.end(); ++sender ) - bufferSystem->addSendingFunction( int_c(sender->first), boost::bind( NonUniformBufferedScheme<Stencil>::send, _1, sender->second ) ); + bufferSystem->addSendingFunction( int_c(sender->first), std::bind( NonUniformBufferedScheme<Stencil>::send, std::placeholders::_1, sender->second ) ); for( auto receiver = ranksToReceiveFrom.begin(); receiver != ranksToReceiveFrom.end(); ++receiver ) - bufferSystem->addReceivingFunction( int_c(*receiver), boost::bind( &NonUniformBufferedScheme<Stencil>::receive, this, _1 ) ); + bufferSystem->addReceivingFunction( int_c(*receiver), std::bind( &NonUniformBufferedScheme<Stencil>::receive, this, std::placeholders::_1 ) ); setupBeforeNextCommunication = char(0); } @@ -931,13 +930,13 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationFineToCoarse( const ui localBuffers.push_back( buffer ); const uint_t bufferIndex = uint_c( localBuffers.size() ) - uint_t(1); - VoidFunction pack = boost::bind( &NonUniformBufferedScheme<Stencil>::localBufferPacking, this, - FINE_TO_COARSE, index, bufferIndex, boost::cref( *packInfo ), block, neighbor, *dir ); + VoidFunction pack = std::bind( &NonUniformBufferedScheme<Stencil>::localBufferPacking, this, + FINE_TO_COARSE, index, bufferIndex, std::cref( *packInfo ), block, neighbor, *dir ); threadsafeLocalCommunication.push_back( pack ); - VoidFunction unpack = boost::bind( &NonUniformBufferedScheme<Stencil>::localBufferUnpacking, this, - FINE_TO_COARSE, index, bufferIndex, boost::cref( *packInfo ), neighbor, block, *dir ); + VoidFunction unpack = std::bind( &NonUniformBufferedScheme<Stencil>::localBufferUnpacking, this, + FINE_TO_COARSE, index, bufferIndex, std::cref( *packInfo ), neighbor, block, *dir ); if( (*packInfo)->threadsafeReceiving() ) threadsafeLocalCommunicationUnpack.push_back( unpack ); @@ -946,7 +945,7 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationFineToCoarse( const ui } else { - VoidFunction localCommunicationFunction = boost::bind( &blockforest::communication::NonUniformPackInfo::communicateLocalFineToCoarse, + VoidFunction localCommunicationFunction = std::bind( &blockforest::communication::NonUniformPackInfo::communicateLocalFineToCoarse, *packInfo, block, neighbor, *dir ); if( (*packInfo)->threadsafeReceiving() ) threadsafeLocalCommunication.push_back( localCommunicationFunction ); @@ -960,10 +959,10 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationFineToCoarse( const ui auto nProcess = block->getNeighborProcess( neighborIdx, uint_t(0) ); if( !packInfos_.empty() ) - sendFunctions[ nProcess ].push_back( boost::bind( NonUniformBufferedScheme<Stencil>::writeHeader, _1, block->getId(), receiverId, *dir ) ); + sendFunctions[ nProcess ].push_back( std::bind( NonUniformBufferedScheme<Stencil>::writeHeader, std::placeholders::_1, block->getId(), receiverId, *dir ) ); for( auto packInfo = packInfos_.begin(); packInfo != packInfos_.end(); ++packInfo ) - sendFunctions[ nProcess ].push_back( boost::bind( &blockforest::communication::NonUniformPackInfo::packDataFineToCoarse, *packInfo, block, receiverId, *dir, _1 ) ); + sendFunctions[ nProcess ].push_back( std::bind( &blockforest::communication::NonUniformPackInfo::packDataFineToCoarse, *packInfo, block, receiverId, *dir, std::placeholders::_1 ) ); } } } @@ -989,10 +988,10 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationFineToCoarse( const ui resetBufferSystem( bufferSystem ); for( auto sender = sendFunctions.begin(); sender != sendFunctions.end(); ++sender ) - bufferSystem->addSendingFunction( int_c(sender->first), boost::bind( NonUniformBufferedScheme<Stencil>::send, _1, sender->second ) ); + bufferSystem->addSendingFunction( int_c(sender->first), std::bind( NonUniformBufferedScheme<Stencil>::send, std::placeholders::_1, sender->second ) ); for( auto receiver = ranksToReceiveFrom.begin(); receiver != ranksToReceiveFrom.end(); ++receiver ) - bufferSystem->addReceivingFunction( int_c(*receiver), boost::bind( &NonUniformBufferedScheme<Stencil>::receive, this, _1 ) ); + bufferSystem->addReceivingFunction( int_c(*receiver), std::bind( &NonUniformBufferedScheme<Stencil>::receive, this, std::placeholders::_1 ) ); setupBeforeNextCommunication = char(0); } diff --git a/src/blockforest/communication/UniformBufferedScheme.h b/src/blockforest/communication/UniformBufferedScheme.h index 393301f6c78039790a97c6f752798e344c1c07a0..1abd5a95592d12247a944137679446bf788e9c43 100644 --- a/src/blockforest/communication/UniformBufferedScheme.h +++ b/src/blockforest/communication/UniformBufferedScheme.h @@ -38,9 +38,7 @@ #include "core/selectable/IsSetSelected.h" #include "core/uid/SUID.h" -#include <boost/bind.hpp> #include <functional> - #include <map> #include <vector> @@ -321,13 +319,13 @@ void UniformBufferedScheme<Stencil>::startCommunication() localBuffers_.push_back( buffer ); const uint_t index = uint_c( localBuffers_.size() ) - uint_t(1); - VoidFunction pack = boost::bind( &UniformBufferedScheme<Stencil>::localBufferPacking, this, - index, boost::cref( *packInfo ), block, *dir ); + VoidFunction pack = std::bind( &UniformBufferedScheme<Stencil>::localBufferPacking, this, + index, std::cref( *packInfo ), block, *dir ); threadsafeLocalCommunication_.push_back( pack ); - VoidFunction unpack = boost::bind( &UniformBufferedScheme<Stencil>::localBufferUnpacking, this, - index, boost::cref( *packInfo ), neighbor, *dir ); + VoidFunction unpack = std::bind( &UniformBufferedScheme<Stencil>::localBufferUnpacking, this, + index, std::cref( *packInfo ), neighbor, *dir ); if( (*packInfo)->threadsafeReceiving() ) threadsafeLocalCommunicationUnpack_.push_back( unpack ); @@ -336,7 +334,7 @@ void UniformBufferedScheme<Stencil>::startCommunication() } else { - VoidFunction localCommunicationFunction = boost::bind( &walberla::communication::UniformPackInfo::communicateLocal, + VoidFunction localCommunicationFunction = std::bind( &walberla::communication::UniformPackInfo::communicateLocal, *packInfo, block, neighbor, *dir ); if( (*packInfo)->threadsafeReceiving() ) threadsafeLocalCommunication_.push_back( localCommunicationFunction ); @@ -350,11 +348,11 @@ void UniformBufferedScheme<Stencil>::startCommunication() auto nProcess = block->getNeighborProcess( neighborIdx, uint_t(0) ); if( !packInfos_.empty() ) - sendFunctions[ nProcess ].push_back( boost::bind( UniformBufferedScheme<Stencil>::writeHeader, _1, nBlockId, *dir ) ); + sendFunctions[ nProcess ].push_back( std::bind( UniformBufferedScheme<Stencil>::writeHeader, std::placeholders::_1, nBlockId, *dir ) ); for( auto packInfo = packInfos_.begin(); packInfo != packInfos_.end(); ++packInfo ) - sendFunctions[ nProcess ].push_back( boost::bind( &walberla::communication::UniformPackInfo::packData, - *packInfo, block, *dir, _1 ) ); + sendFunctions[ nProcess ].push_back( std::bind( &walberla::communication::UniformPackInfo::packData, + *packInfo, block, *dir, std::placeholders::_1 ) ); } } } @@ -368,8 +366,8 @@ void UniformBufferedScheme<Stencil>::startCommunication() for( auto sender = sendFunctions.begin(); sender != sendFunctions.end(); ++sender ) { - bufferSystem_.addSendingFunction ( int_c(sender->first), boost::bind( UniformBufferedScheme<Stencil>::send, _1, sender->second ) ); - bufferSystem_.addReceivingFunction( int_c(sender->first), boost::bind( &UniformBufferedScheme<Stencil>::receive, this, _1 ) ); + bufferSystem_.addSendingFunction ( int_c(sender->first), std::bind( UniformBufferedScheme<Stencil>::send, std::placeholders::_1, sender->second ) ); + bufferSystem_.addReceivingFunction( int_c(sender->first), std::bind( &UniformBufferedScheme<Stencil>::receive, this, std::placeholders::_1 ) ); } setupBeforeNextCommunication_ = false; @@ -539,13 +537,13 @@ void UniformBufferedScheme<Stencil>::localBufferUnpacking( const uint_t index, c template< typename Stencil > std::function<void()> UniformBufferedScheme<Stencil>::getStartCommunicateFunctor() { - return boost::bind( &UniformBufferedScheme::startCommunication, this ); + return std::bind( &UniformBufferedScheme::startCommunication, this ); } template< typename Stencil > std::function<void()> UniformBufferedScheme<Stencil>::getWaitFunctor() { - return boost::bind( &UniformBufferedScheme::wait, this ); + return std::bind( &UniformBufferedScheme::wait, this ); } diff --git a/src/blockforest/communication/UniformDirectScheme.h b/src/blockforest/communication/UniformDirectScheme.h index 16d6e9fdda939275ba60ce3ef22aa98b5db9f143..86393089342eb96c0134148a3518647b0cb2d7d0 100644 --- a/src/blockforest/communication/UniformDirectScheme.h +++ b/src/blockforest/communication/UniformDirectScheme.h @@ -32,6 +32,8 @@ #include <vector> #include <map> +#include <functional> + #include "communication/UniformMPIDatatypeInfo.h" namespace walberla { @@ -112,8 +114,8 @@ public: void startCommunication(); void wait(); - std::function<void()> getStartCommunicateFunctor() { return boost::bind( &UniformDirectScheme::startCommunication, this ); } - std::function<void()> getWaitFunctor() { return boost::bind( &UniformDirectScheme::wait, this ); } + std::function<void()> getStartCommunicateFunctor() { return std::bind( &UniformDirectScheme::startCommunication, this ); } + std::function<void()> getWaitFunctor() { return std::bind( &UniformDirectScheme::wait, this ); } //@} //******************************************************************************************************************* diff --git a/src/blockforest/loadbalancing/DynamicCurve.h b/src/blockforest/loadbalancing/DynamicCurve.h index d9767ecf055e8b1106bbcd2746381c5be4b89db1..d72b60726f0b1dab41e8e5708051b1bc7b238a22 100644 --- a/src/blockforest/loadbalancing/DynamicCurve.h +++ b/src/blockforest/loadbalancing/DynamicCurve.h @@ -792,8 +792,9 @@ void DynamicCurveBalance< PhantomData_T >::balanceWeighted( const std::vector< s long double weight( 0 ); int numBlocks( 0 ); while( c < blocks.size() && - std::abs( pWeight - weight - numeric_cast< long double >( allBlocks[ uint_c( blocks[c].first ) ][ blocks[c].second ].second ) ) <= - std::abs( pWeight - weight ) && + ( isIdentical(weight, 0.0l) || + std::abs( pWeight - weight - numeric_cast< long double >( allBlocks[ uint_c( blocks[c].first ) ][ blocks[c].second ].second ) ) <= + std::abs( pWeight - weight ) ) && numBlocks < maxBlocksPerProcess_ ) { targets[ uint_c( blocks[c].first ) ][ blocks[c].second ] = pid_c(p); diff --git a/src/blockforest/loadbalancing/DynamicDiffusive.h b/src/blockforest/loadbalancing/DynamicDiffusive.h index b914bda506fbd87db247e4bc6389727ed13a5142..d9037070bad849a6a751f2ed4d72c26cba33bbd0 100644 --- a/src/blockforest/loadbalancing/DynamicDiffusive.h +++ b/src/blockforest/loadbalancing/DynamicDiffusive.h @@ -409,8 +409,8 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai const uint_t level = levelwise_ ? block->getLevel() : uint_t(0); if( level == l && targetProcess[i].second == blockforest.getProcess() ) { - const uint_t * faces = blockforest::getFaceNeighborhoodSectionIndices(); - for( uint_t j = uint_t(0); j != uint_t(6); ++j ) + auto faces = blockforest::getFaceNeighborhoodSectionIndices(); + for( uint_t j = uint_t(0); j != faces.size(); ++j ) { const uint_t sectionIndex = faces[j]; const uint_t sectionSize = block->getNeighborhoodSectionSize( sectionIndex ); @@ -427,8 +427,8 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai } } } - const uint_t * edges = blockforest::getEdgeNeighborhoodSectionIndices(); - for( uint_t j = uint_t(0); j != uint_t(12); ++j ) + auto edges = blockforest::getEdgeNeighborhoodSectionIndices(); + for( uint_t j = uint_t(0); j != edges.size(); ++j ) { const uint_t sectionIndex = edges[j]; const uint_t sectionSize = block->getNeighborhoodSectionSize( sectionIndex ); @@ -445,8 +445,8 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai } } } - const uint_t * corners = blockforest::getCornerNeighborhoodSectionIndices(); - for( uint_t j = uint_t(0); j != uint_t(8); ++j ) + auto corners = blockforest::getCornerNeighborhoodSectionIndices(); + for( uint_t j = uint_t(0); j != corners.size(); ++j ) { const uint_t sectionIndex = corners[j]; const uint_t sectionSize = block->getNeighborhoodSectionSize( sectionIndex ); @@ -655,8 +655,8 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai { if( regardConnectivity_ && iteration < disregardConnectivityStart_ ) { - const uint_t * faces = blockforest::getFaceNeighborhoodSectionIndices(); - for( uint_t j = uint_t(0); j != uint_t(6); ++j ) + auto faces = blockforest::getFaceNeighborhoodSectionIndices(); + for( uint_t j = uint_t(0); j != faces.size(); ++j ) { const uint_t sectionIndex = faces[j]; const uint_t sectionSize = block->getNeighborhoodSectionSize( sectionIndex ); @@ -675,8 +675,8 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai } } } - const uint_t * edges = blockforest::getEdgeNeighborhoodSectionIndices(); - for( uint_t j = uint_t(0); j != uint_t(12); ++j ) + auto edges = blockforest::getEdgeNeighborhoodSectionIndices(); + for( uint_t j = uint_t(0); j != edges.size(); ++j ) { const uint_t sectionIndex = edges[j]; const uint_t sectionSize = block->getNeighborhoodSectionSize( sectionIndex ); @@ -695,8 +695,8 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai } } } - const uint_t * corners = blockforest::getCornerNeighborhoodSectionIndices(); - for( uint_t j = uint_t(0); j != uint_t(8); ++j ) + auto corners = blockforest::getCornerNeighborhoodSectionIndices(); + for( uint_t j = uint_t(0); j != corners.size(); ++j ) { const uint_t sectionIndex = corners[j]; const uint_t sectionSize = block->getNeighborhoodSectionSize( sectionIndex ); diff --git a/src/blockforest/loadbalancing/DynamicParMetis.cpp b/src/blockforest/loadbalancing/DynamicParMetis.cpp index 0ec01197de2e98535cf4e0dc225ef3453518e718..0e215b6f92bc7b8bd835d165b2b76b7892e9c06b 100644 --- a/src/blockforest/loadbalancing/DynamicParMetis.cpp +++ b/src/blockforest/loadbalancing/DynamicParMetis.cpp @@ -136,21 +136,6 @@ bool DynamicParMetis::operator()( std::vector< std::pair< const PhantomBlock *, MPI_Group_incl(allGroup, int_c(ranks.size()), &ranks[0], &subGroup); MPI_Comm_create( MPIManager::instance()->comm(), subGroup, &subComm); - if ( targetProcess.size() != 0) - { - int subRank; - int subSize; - MPI_Comm_rank(subComm, &subRank); - MPI_Comm_size(subComm, &subSize); - WALBERLA_CHECK_GREATER_EQUAL(subRank, 0); - WALBERLA_CHECK_LESS(subRank, subSize); - } else - { - int subRank; - MPI_Comm_rank(subComm, &subRank); - WALBERLA_CHECK_EQUAL(subRank, MPI_UNDEFINED); - } - int64_t edgecut = 0; WALBERLA_CHECK_EQUAL( phantomForest.getNumberOfBlocks(), targetProcess.size() ); std::vector<int64_t> part( targetProcess.size(), int64_c( MPIManager::instance()->rank() ) ); diff --git a/src/blockforest/loadbalancing/StaticCurve.cpp b/src/blockforest/loadbalancing/StaticCurve.cpp index 9bb9c184dcc24b10cfd1bc93f388d59523911301..e90ec3bc10ac72a04ebbfe9ce6609552c4276158 100644 --- a/src/blockforest/loadbalancing/StaticCurve.cpp +++ b/src/blockforest/loadbalancing/StaticCurve.cpp @@ -123,9 +123,9 @@ uint_t StaticLevelwiseCurveBalanceWeighted::operator()( SetupBlockForest & fores { const workload_t pWeight = totalWeight / workload_c( numberOfProcesses - p ); workload_t weight( 0 ); - while( c < blocksOnLevel.size() && + while( c < blocksOnLevel.size() && ( isIdentical(weight, workload_t(0)) || std::abs( pWeight - weight - blocksOnLevel[c]->getWorkload() ) <= - std::abs( pWeight - weight ) ) + std::abs( pWeight - weight ) ) ) { blocksOnLevel[c]->assignTargetProcess(p); diff --git a/src/blockforest/python/CommunicationExport.impl.h b/src/blockforest/python/CommunicationExport.impl.h index 934058546dff76d23f794f89a63880b42fc7192d..09041944f0ba0cf342c4a80fcf42e9e23abd207f 100644 --- a/src/blockforest/python/CommunicationExport.impl.h +++ b/src/blockforest/python/CommunicationExport.impl.h @@ -106,7 +106,7 @@ namespace internal const int tag ) { UniformBufferedSchemeCreator creator( bf, stencil, tag ); - python_coupling::for_each_noncopyable_type< Stencils > ( boost::ref(creator) ); + python_coupling::for_each_noncopyable_type< Stencils > ( std::ref(creator) ); if ( creator.getResult() == boost::python::object() ) { @@ -185,7 +185,7 @@ namespace internal const std::string & stencil, const int tag ) { UniformDirectSchemeCreator creator( bf, stencil, tag ); - python_coupling::for_each_noncopyable_type< Stencils > ( boost::ref(creator) ); + python_coupling::for_each_noncopyable_type< Stencils > ( std::ref(creator) ); if ( creator.getResult() == boost::python::object() ) { diff --git a/src/core/Abort.cpp b/src/core/Abort.cpp index 910dcb209f178dcdd1595477f8339eb08726d06a..1ff3ad2cb045f2132518f6a854fd79f48053a1a8 100644 --- a/src/core/Abort.cpp +++ b/src/core/Abort.cpp @@ -63,7 +63,7 @@ void Abort::defaultAbort( const std::string & logMessage, const std::string & ca #ifdef _OPENMP - #pragma omp critical (abort) + #pragma omp critical (Abort_abort) { #endif diff --git a/src/core/DataTypes.h b/src/core/DataTypes.h index b0442f52466f8fcbe13ef68656a9b99ad449cbb2..4c348dfe7f6e934fb9fb5403abfd5761e256a9ae 100644 --- a/src/core/DataTypes.h +++ b/src/core/DataTypes.h @@ -42,7 +42,6 @@ namespace walberla { template <typename> struct never_true : std::false_type {}; - // shared ptr using std::shared_ptr; @@ -50,9 +49,6 @@ using std::weak_ptr; using std::make_shared; using std::dynamic_pointer_cast; -// functions, use this when "function" namespace is no longer needed -//using std::function; -//using std::bind; // numeric cast (performs range checks in debug mode) diff --git a/src/core/Environment.cpp b/src/core/Environment.cpp index 6e69586542c142abe99a9a05eafdb1e6bf47eb6f..b39a0b304c58ebe65356a587ec4264c7fe3c2754 100644 --- a/src/core/Environment.cpp +++ b/src/core/Environment.cpp @@ -31,10 +31,9 @@ #include "core/uid/SUID.h" #include <boost/algorithm/string.hpp> -#include <boost/bind.hpp> -#include <boost/foreach.hpp> #include <algorithm> +#include <functional> #include <sstream> #include <string> @@ -85,7 +84,7 @@ void configureGlobalState( const shared_ptr<Config> & config ) { std::vector< std::string > states; boost::split( states, suids, boost::is_any_of(", \t") ); - states.erase( std::remove_if( states.begin(), states.end(), boost::bind( &std::string::empty, _1 ) ), states.end() ); + states.erase( std::remove_if( states.begin(), states.end(), std::bind( &std::string::empty, std::placeholders::_1 ) ), states.end() ); Set<SUID> state; for( auto it = states.begin(); it != states.end(); ++it ) diff --git a/src/core/cell/CellInterval.cpp b/src/core/cell/CellInterval.cpp index 78f4501f0e1b6fb6db813b81b7ab4cf132f1091b..83ab0e33df531b98fc0505d05213e31ed3066457 100644 --- a/src/core/cell/CellInterval.cpp +++ b/src/core/cell/CellInterval.cpp @@ -23,8 +23,6 @@ #include "CellSet.h" #include "CellVector.h" -#include <boost/foreach.hpp> - namespace walberla { namespace cell { @@ -51,7 +49,7 @@ bool CellInterval::overlaps( const CellVector& cellVector ) const if( empty() ) return false; - BOOST_FOREACH( const Cell & cell, cellVector ) + for( const Cell & cell : cellVector ) { if( this->contains( cell ) ) return true; diff --git a/src/core/config/ConfigToBoostPropertyTree.cpp b/src/core/config/ConfigToBoostPropertyTree.cpp index 7fcc13247d9a7770e386469e69dc290aa9411a41..e3b5e6b40bc0ead8cd49fce3aba4c432f407d710 100644 --- a/src/core/config/ConfigToBoostPropertyTree.cpp +++ b/src/core/config/ConfigToBoostPropertyTree.cpp @@ -21,7 +21,6 @@ #include "ConfigToBoostPropertyTree.h" -#include <boost/foreach.hpp> #include <boost/property_tree/ptree.hpp> @@ -39,7 +38,7 @@ boost::property_tree::iptree configBlockHandleToBoostPropertyTree( const Config: Config::Blocks blocks; blockHandle.getBlocks(blocks); - BOOST_FOREACH( const Config::BlockHandle & handle, blocks ) + for( const Config::BlockHandle & handle : blocks ) propTree.add_child( handle.getKey(), configBlockHandleToBoostPropertyTree( handle ) ); return propTree; diff --git a/src/core/debug/Debug.h b/src/core/debug/Debug.h index 3ea4bcd054c16039fb2adedfaf4e8043ed38ff5c..b29d2824e157033614e5cbf09ae4a6a076c70edd 100644 --- a/src/core/debug/Debug.h +++ b/src/core/debug/Debug.h @@ -26,8 +26,8 @@ #ifndef NDEBUG # include "CheckFunctions.h" # include <functional> -# include <boost/bind.hpp> # include <string> +# include "core/Macros.h" #endif @@ -265,7 +265,7 @@ private: /// \endcond #define WALBERLA_ASSERT_SECTION(condition) if(true)\ - if(const walberla::debug::ConditionalExec COND_EXEC = walberla::debug::ConditionalExec(!(condition),boost::bind(walberla::debug::myAssert,__FILE__,__LINE__))) + if(const walberla::debug::ConditionalExec COND_EXEC = walberla::debug::ConditionalExec(!(condition),std::bind(walberla::debug::myAssert,__FILE__,__LINE__))) #else diff --git a/src/core/math/GenericAABB.h b/src/core/math/GenericAABB.h index aa8e15ac57be558db072a0aef155bde677c97d52..270a7a53f469dcb8e3ea0e9769002a77727f3b8e 100644 --- a/src/core/math/GenericAABB.h +++ b/src/core/math/GenericAABB.h @@ -167,6 +167,7 @@ public: inline void extend( const value_type e ); inline void extend( const vector_type & e ); + inline void setCenter( const vector_type & center ); inline void translate( const vector_type & translation ); inline void scale( const value_type factor ); diff --git a/src/core/math/GenericAABB.impl.h b/src/core/math/GenericAABB.impl.h index 5709d770e51cf1f03ff81f3c9e322032b35325d6..00503076fc82fc8390cb60feb5ca5456edbf686c 100644 --- a/src/core/math/GenericAABB.impl.h +++ b/src/core/math/GenericAABB.impl.h @@ -33,7 +33,7 @@ template< typename T > GenericAABB< T >::GenericAABB() : minCorner_( value_type(0), value_type(0), value_type(0) ), maxCorner_( value_type(0), value_type(0), value_type(0) ) { - WALBERLA_ASSERT( checkInvariant() ); + WALBERLA_ASSERT( checkInvariant(), *this ); WALBERLA_ASSERT( empty() ); } @@ -51,7 +51,7 @@ inline GenericAABB< T >::GenericAABB( const GenericAABB< U > & other ) : minCorner_( other.minCorner() ), maxCorner_( other.maxCorner() ) { - WALBERLA_ASSERT( checkInvariant() ); + WALBERLA_ASSERT( checkInvariant(), *this ); } @@ -78,7 +78,7 @@ GenericAABB< T >::GenericAABB( const vector_type & corner0, const vector_type & } } - WALBERLA_ASSERT( checkInvariant() ); + WALBERLA_ASSERT( checkInvariant(), *this ); } @@ -130,7 +130,7 @@ GenericAABB< T >::GenericAABB( const value_type x0, const value_type y0, const v maxCorner_[2] = z0; } - WALBERLA_ASSERT( checkInvariant() ); + WALBERLA_ASSERT( checkInvariant(), *this ); } @@ -160,7 +160,7 @@ GenericAABB< T >::GenericAABB( InputIterator first, InputIterator last ) init(); } - WALBERLA_ASSERT( checkInvariant() ); + WALBERLA_ASSERT( checkInvariant(), *this ); } @@ -177,7 +177,7 @@ template< typename T > GenericAABB< T >::GenericAABB( const vector_type & theMinCorner, const vector_type & theMaxCorner, MinMaxCornerGivenT ) : minCorner_( theMinCorner ), maxCorner_( theMaxCorner ) { - WALBERLA_ASSERT( checkInvariant() ); + WALBERLA_ASSERT( checkInvariant(), *this ); } @@ -200,7 +200,7 @@ GenericAABB< T >::GenericAABB( const GenericAABB & lhs, const GenericAABB & rhs std::max( minCorner_[1], std::min( lhs.maxCorner_[1], rhs.maxCorner_[1] ) ), std::max( minCorner_[2], std::min( lhs.maxCorner_[2], rhs.maxCorner_[2] ) ) ) { - WALBERLA_ASSERT( checkInvariant() ); + WALBERLA_ASSERT( checkInvariant(), *this ); } @@ -222,7 +222,7 @@ GenericAABB< T >::GenericAABB( const value_type minX, const value_type minY, con const value_type maxX, const value_type maxY, const value_type maxZ, MinMaxCornerGivenT ) : minCorner_( minX, minY, minZ ), maxCorner_( maxX, maxY, maxZ ) { - WALBERLA_ASSERT( checkInvariant() ); + WALBERLA_ASSERT( checkInvariant(), *this ); } @@ -491,7 +491,6 @@ template< typename T > typename GenericAABB< T >::value_type GenericAABB< T >::volume() const { WALBERLA_ASSERT( checkInvariant() ); - return ( maxCorner_[0] - minCorner_[0] ) * ( maxCorner_[1] - minCorner_[1] ) * ( maxCorner_[2] - minCorner_[2] ); } @@ -1563,6 +1562,21 @@ void GenericAABB< T >::extend( const vector_type & e ) +/** + * \brief Sets center of this GenericAABB + * + * AABB gets translated such that its center matches the given center. + * + * \param new center location + */ +template< typename T > +void GenericAABB< T >::setCenter( const vector_type & center ) +{ + translate(center - this->center()); +} + + + /** * \brief Translates this GenericAABB * diff --git a/src/core/math/Matrix3.h b/src/core/math/Matrix3.h index 27a29b9450d6c9d95630440b7ffc346d6e0fa630..fe3c0e00cac880cb6d59b29af401e87226dc7c92 100644 --- a/src/core/math/Matrix3.h +++ b/src/core/math/Matrix3.h @@ -1839,3 +1839,30 @@ namespace mpi { }; } } + +//====================================================================================================================== +// +// MPI Datatype +// +//====================================================================================================================== + +namespace walberla { + + template< typename T> + struct MPITrait< Matrix3<T> > + { + static inline MPI_Datatype type() + { + // cannot use mpi::Datatype here because its destructor calls MPI_Type_free and static variables are destroyed after the MPI_Finalize + static MPI_Datatype datatype; + static bool initialized = false; + + if( ! initialized ) { + MPI_Type_contiguous(9, MPITrait<T>::type(), &datatype ); + MPI_Type_commit( &datatype ); + initialized = true; + } + return datatype; + } + }; +} // namespace walberla diff --git a/src/core/math/Random.cpp b/src/core/math/Random.cpp index 72707f208e5053cba44daed005e2685f86333e8b..5acdc01d34fbe236fcb94fb98fa952a92564eaa2 100644 --- a/src/core/math/Random.cpp +++ b/src/core/math/Random.cpp @@ -43,7 +43,7 @@ std::mt19937 & getGenerator() // std::mt19937_64 void seedRandomGenerator( const std::mt19937::result_type & seed ) { #ifdef _OPENMP - #pragma omp critical (random) + #pragma omp critical (Random_random) #endif internal::getGenerator().seed( seed ); } diff --git a/src/core/math/Random.h b/src/core/math/Random.h index ec61aa51d65b76f3a10c243086d08a48eb166590..d63d2e7ede6338606219e743d7fc44444ca23010 100644 --- a/src/core/math/Random.h +++ b/src/core/math/Random.h @@ -59,7 +59,7 @@ INT intRandom( const INT min, const INT max, std::mt19937 & generator ) INT value; #ifdef _OPENMP - #pragma omp critical (random) + #pragma omp critical (Random_random) #endif { value = distribution( generator ); } @@ -76,7 +76,7 @@ inline char intRandom<char>( const char min, const char max, std::mt19937 & gene char value; #ifdef _OPENMP - #pragma omp critical (random) + #pragma omp critical (Random_random) #endif { value = static_cast<char>( distribution( generator ) ); } @@ -93,7 +93,7 @@ inline unsigned char intRandom<unsigned char>( const unsigned char min, const un unsigned char value; #ifdef _OPENMP - #pragma omp critical (random) + #pragma omp critical (Random_random) #endif { value = static_cast<unsigned char>( distribution( generator ) ); } @@ -110,7 +110,7 @@ inline signed char intRandom<signed char>( const signed char min, const signed c signed char value; #ifdef _OPENMP - #pragma omp critical (random) + #pragma omp critical (Random_random) #endif { value = static_cast<signed char>( distribution( generator ) ); } @@ -168,7 +168,7 @@ REAL realRandom( const REAL min = REAL(0), const REAL max = REAL(1), std::mt1993 REAL value; #ifdef _OPENMP - #pragma omp critical (random) + #pragma omp critical (Random_random) #endif { value = distribution( generator ); } diff --git a/src/core/math/Vector2.h b/src/core/math/Vector2.h index 1ad6f9cab05d9eda80a0684d736e5921ba26b5d0..145bf302fb636ab269fbc8930c4fd74d5bf4844b 100644 --- a/src/core/math/Vector2.h +++ b/src/core/math/Vector2.h @@ -1696,13 +1696,13 @@ namespace walberla { { static inline MPI_Datatype type() { - static mpi::Datatype datatype; + // cannot use mpi::Datatype here because its destructor calls MPI_Type_free and static variables are destroyed after the MPI_Finalize + static MPI_Datatype datatype; static bool initialized = false; if( ! initialized ) { - MPI_Datatype newDatatype; - MPI_Type_contiguous(2, MPITrait<T>::type(), &newDatatype ); - datatype.init( newDatatype ); + MPI_Type_contiguous(2, MPITrait<T>::type(), &datatype ); + MPI_Type_commit( &datatype ); initialized = true; } return datatype; diff --git a/src/core/math/Vector3.h b/src/core/math/Vector3.h index f5b1ea819cff09f5813a162574ee318ab8bd7fa7..662d2dfa59c9d32eb89efdac064f01d03437b568 100644 --- a/src/core/math/Vector3.h +++ b/src/core/math/Vector3.h @@ -1895,13 +1895,13 @@ namespace walberla { { static inline MPI_Datatype type() { - static mpi::Datatype datatype; + // cannot use mpi::Datatype here because its destructor calls MPI_Type_free and static variables are destroyed after the MPI_Finalize + static MPI_Datatype datatype; static bool initialized = false; if( ! initialized ) { - MPI_Datatype newDatatype; - MPI_Type_contiguous(3, MPITrait<T>::type(), &newDatatype ); - datatype.init( newDatatype ); + MPI_Type_contiguous(3, MPITrait<T>::type(), &datatype ); + MPI_Type_commit( &datatype ); initialized = true; } return datatype; diff --git a/src/core/math/extern/exprtk.h b/src/core/math/extern/exprtk.h index 1a4423e4a4edffd3b4df85173811eaede9c45c45..f55657a617e1d7815b9f154fd073dcf843eed2ac 100644 --- a/src/core/math/extern/exprtk.h +++ b/src/core/math/extern/exprtk.h @@ -2,7 +2,7 @@ ****************************************************************** * C++ Mathematical Expression Toolkit Library * * * - * Author: Arash Partow (1999-2017) * + * Author: Arash Partow (1999-2018) * * URL: http://www.partow.net/programming/exprtk/index.html * * * * Copyright notice: * @@ -67,7 +67,7 @@ namespace exprtk #define exprtk_error_location \ "exprtk.hpp:" + details::to_str(__LINE__) \ - #if __GNUC__ >= 7 + #if defined(__GNUC__) && (__GNUC__ >= 7) #define exprtk_disable_fallthrough_begin \ _Pragma ("GCC diagnostic push") \ @@ -83,8 +83,12 @@ namespace exprtk namespace details { - typedef unsigned char uchar_t; - typedef char char_t; + typedef unsigned char uchar_t; + typedef char char_t; + typedef uchar_t* uchar_ptr; + typedef char_t* char_ptr; + typedef uchar_t const* uchar_cptr; + typedef char_t const* char_cptr; inline bool is_whitespace(const char_t c) { @@ -283,6 +287,11 @@ namespace exprtk return result; } + inline std::string to_str(std::size_t i) + { + return to_str(static_cast<int>(i)); + } + inline bool is_hex_digit(const std::string::value_type digit) { return (('0' <= digit) && (digit <= '9')) || @@ -384,7 +393,7 @@ namespace exprtk return (*this); } - inline build_string& operator << (const char_t* s) + inline build_string& operator << (char_cptr s) { data_ += std::string(s); return (*this); @@ -577,77 +586,62 @@ namespace exprtk const typename std::iterator_traits<Iterator>::value_type& zero_or_more, const typename std::iterator_traits<Iterator>::value_type& zero_or_one) { - if (0 == std::distance(data_begin,data_end)) - { - return false; - } - Iterator d_itr = data_begin; Iterator p_itr = pattern_begin; - Iterator c_itr = data_begin; - Iterator m_itr = data_begin; - while ((data_end != d_itr) && (zero_or_more != (*p_itr))) + while ((p_itr != pattern_end) && (d_itr != data_end)) { - if ((!Compare::cmp((*p_itr),(*d_itr))) && (zero_or_one != (*p_itr))) + if (zero_or_more == *p_itr) { - return false; - } + while ((p_itr != pattern_end) && (*p_itr == zero_or_more || *p_itr == zero_or_one)) + { + ++p_itr; + } - ++p_itr; - ++d_itr; - } + if (p_itr == pattern_end) + return true; - while (data_end != d_itr) - { - if (zero_or_more == (*p_itr)) - { - if (pattern_end == (++p_itr)) + const typename std::iterator_traits<Iterator>::value_type c = *(p_itr++); + + while ((d_itr != data_end) && !Compare::cmp(c,*d_itr)) { - return true; + ++d_itr; } - m_itr = p_itr; - c_itr = d_itr; - ++c_itr; + ++d_itr; } - else if ((Compare::cmp((*p_itr),(*d_itr))) || (zero_or_one == (*p_itr))) + else if ((*p_itr == zero_or_one) || Compare::cmp(*p_itr, *d_itr)) { - ++p_itr; ++d_itr; + ++p_itr; } else - { - p_itr = m_itr; - d_itr = c_itr++; - } + return false; } - while ((p_itr != pattern_end) && (zero_or_more == (*p_itr))) { ++p_itr; } - - return (p_itr == pattern_end); + return (d_itr == data_end) && (p_itr == pattern_end); } inline bool wc_match(const std::string& wild_card, const std::string& str) { - return match_impl<const char_t*,cs_match>(wild_card.data(), - wild_card.data() + wild_card.size(), - str.data(), - str.data() + str.size(), - '*', - '?'); + return match_impl<char_cptr,cs_match>(wild_card.data(), + wild_card.data() + wild_card.size(), + str.data(), + str.data() + str.size(), + '*', + '?'); } inline bool wc_imatch(const std::string& wild_card, const std::string& str) { - return match_impl<const char_t*,cis_match>(wild_card.data(), - wild_card.data() + wild_card.size(), - str.data(), - str.data() + str.size(), - '*', - '?'); + return match_impl<char_cptr,cis_match>(wild_card.data(), + wild_card.data() + wild_card.size(), + str.data(), + str.data() + str.size(), + '*', + '?'); } inline bool sequence_match(const std::string& pattern, @@ -728,7 +722,7 @@ namespace exprtk 1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016 }; - static const std::size_t pow10_size = sizeof(pow10) / sizeof(double); + static const std::size_t pow10_size = sizeof(pow10) / sizeof(double); namespace numeric { @@ -749,22 +743,28 @@ namespace exprtk namespace details { struct unknown_type_tag { unknown_type_tag() {} }; - struct real_type_tag { real_type_tag() {} }; + struct real_type_tag { real_type_tag () {} }; struct complex_type_tag { complex_type_tag() {} }; - struct int_type_tag { int_type_tag() {} }; + struct int_type_tag { int_type_tag () {} }; template <typename T> - struct number_type { typedef unknown_type_tag type; }; + struct number_type + { + typedef unknown_type_tag type; + number_type() {} + }; - #define exprtk_register_real_type_tag(T) \ - template<> struct number_type<T> { typedef real_type_tag type; }; \ + #define exprtk_register_real_type_tag(T) \ + template<> struct number_type<T> \ + { typedef real_type_tag type; number_type() {} }; \ - #define exprtk_register_complex_type_tag(T) \ - template<> struct number_type<std::complex<T> > \ - { typedef complex_type_tag type; }; \ + #define exprtk_register_complex_type_tag(T) \ + template<> struct number_type<std::complex<T> > \ + { typedef complex_type_tag type; number_type() {} }; \ - #define exprtk_register_int_type_tag(T) \ - template<> struct number_type<T> { typedef int_type_tag type; }; \ + #define exprtk_register_int_type_tag(T) \ + template<> struct number_type<T> \ + { typedef int_type_tag type; number_type() {} }; \ exprtk_register_real_type_tag(double ) exprtk_register_real_type_tag(long double) @@ -984,7 +984,15 @@ namespace exprtk template <typename T> inline T root_impl(const T v0, const T v1, real_type_tag) { - return std::pow(v0,T(1) / v1); + if (v1 < T(0)) + return std::numeric_limits<T>::quiet_NaN(); + + const std::size_t n = static_cast<std::size_t>(v1); + + if ((v0 < T(0)) && (0 == (n % 2))) + return std::numeric_limits<T>::quiet_NaN(); + + return std::pow(v0, T(1) / n); } template <typename T> @@ -1297,6 +1305,9 @@ namespace exprtk template <typename T> inline T frac_impl(const T v, real_type_tag) { return (v - static_cast<long long>(v)); } template <typename T> inline T trunc_impl(const T v, real_type_tag) { return T(static_cast<long long>(v)); } + template <typename T> inline T const_pi_impl(real_type_tag) { return T(numeric::constant::pi); } + template <typename T> inline T const_e_impl (real_type_tag) { return T(numeric::constant::e); } + template <typename T> inline T abs_impl(const T v, int_type_tag) { return ((v >= T(0)) ? v : -v); } template <typename T> inline T exp_impl(const T v, int_type_tag) { return std::exp (v); } template <typename T> inline T log_impl(const T v, int_type_tag) { return std::log (v); } @@ -1351,161 +1362,161 @@ namespace exprtk template <typename T> inline int to_int32(const T v) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return to_int32_impl(v, num_type); } template <typename T> inline long long int to_int64(const T v) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return to_int64_impl(v, num_type); } template <typename T> inline bool is_nan(const T v) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return is_nan_impl(v, num_type); } template <typename T> inline T min(const T v0, const T v1) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return min_impl(v0, v1, num_type); } template <typename T> inline T max(const T v0, const T v1) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return max_impl(v0, v1, num_type); } template <typename T> inline T equal(const T v0, const T v1) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return equal_impl(v0, v1, num_type); } template <typename T> inline T nequal(const T v0, const T v1) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return nequal_impl(v0, v1, num_type); } template <typename T> inline T modulus(const T v0, const T v1) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return modulus_impl(v0, v1, num_type); } template <typename T> inline T pow(const T v0, const T v1) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return pow_impl(v0, v1, num_type); } template <typename T> inline T logn(const T v0, const T v1) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return logn_impl(v0, v1, num_type); } template <typename T> inline T root(const T v0, const T v1) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return root_impl(v0, v1, num_type); } template <typename T> inline T roundn(const T v0, const T v1) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return roundn_impl(v0, v1, num_type); } template <typename T> inline T hypot(const T v0, const T v1) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return hypot_impl(v0, v1, num_type); } template <typename T> inline T atan2(const T v0, const T v1) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return atan2_impl(v0, v1, num_type); } template <typename T> inline T shr(const T v0, const T v1) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return shr_impl(v0, v1, num_type); } template <typename T> inline T shl(const T v0, const T v1) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return shl_impl(v0, v1, num_type); } template <typename T> inline T and_opr(const T v0, const T v1) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return and_impl(v0, v1, num_type); } template <typename T> inline T nand_opr(const T v0, const T v1) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return nand_impl(v0, v1, num_type); } template <typename T> inline T or_opr(const T v0, const T v1) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return or_impl(v0, v1, num_type); } template <typename T> inline T nor_opr(const T v0, const T v1) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return nor_impl(v0, v1, num_type); } template <typename T> inline T xor_opr(const T v0, const T v1) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return xor_impl(v0, v1, num_type); } template <typename T> inline T xnor_opr(const T v0, const T v1) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return xnor_impl(v0, v1, num_type); } template <typename T> inline bool is_integer(const T v) { - typename details::number_type<T>::type num_type; + const typename details::number_type<T>::type num_type; return is_integer_impl(v, num_type); } @@ -1545,13 +1556,13 @@ namespace exprtk template <typename T> struct fast_exp<T, 1> { static inline T result(T v) { return v; } }; template <typename T> struct fast_exp<T, 0> { static inline T result(T ) { return T(1); } }; - #define exprtk_define_unary_function(FunctionName) \ - template <typename T> \ - inline T FunctionName (const T v) \ - { \ - typename details::number_type<T>::type num_type; \ - return FunctionName##_impl(v,num_type); \ - } \ + #define exprtk_define_unary_function(FunctionName) \ + template <typename T> \ + inline T FunctionName (const T v) \ + { \ + const typename details::number_type<T>::type num_type; \ + return FunctionName##_impl(v,num_type); \ + } \ exprtk_define_unary_function(abs ) exprtk_define_unary_function(acos ) @@ -1776,7 +1787,7 @@ namespace exprtk if ((3 != length) && (inf_length != length)) return false; - const char_t* inf_itr = ('i' == (*itr)) ? inf_lc : inf_uc; + char_cptr inf_itr = ('i' == (*itr)) ? inf_lc : inf_uc; while (end != itr) { @@ -1964,8 +1975,8 @@ namespace exprtk { const typename numeric::details::number_type<T>::type num_type; - const char_t* begin = s.data(); - const char_t* end = s.data() + s.size(); + char_cptr begin = s.data(); + char_cptr end = s.data() + s.size(); return string_to_real(begin, end, t, num_type); } @@ -2204,9 +2215,7 @@ namespace exprtk { scan_token(); - if (token_list_.empty()) - return true; - else if (token_list_.back().is_error()) + if (!token_list_.empty() && token_list_.back().is_error()) return false; } @@ -2296,8 +2305,8 @@ namespace exprtk inline std::string substr(const std::size_t& begin, const std::size_t& end) { - const char_t* begin_itr = ((base_itr_ + begin) < s_end_) ? (base_itr_ + begin) : s_end_; - const char_t* end_itr = ((base_itr_ + end) < s_end_) ? (base_itr_ + end) : s_end_; + details::char_cptr begin_itr = ((base_itr_ + begin) < s_end_) ? (base_itr_ + begin) : s_end_; + details::char_cptr end_itr = ((base_itr_ + end) < s_end_) ? (base_itr_ + end) : s_end_; return std::string(begin_itr,end_itr); } @@ -2314,11 +2323,28 @@ namespace exprtk private: - inline bool is_end(const char_t* itr) + inline bool is_end(details::char_cptr itr) { return (s_end_ == itr); } + inline bool is_comment_start(details::char_cptr itr) + { + #ifndef exprtk_disable_comments + const char_t c0 = *(itr + 0); + const char_t c1 = *(itr + 1); + + if ('#' == c0) + return true; + else if (!is_end(itr + 1)) + { + if (('/' == c0) && ('/' == c1)) return true; + if (('/' == c0) && ('*' == c1)) return true; + } + #endif + return false; + } + inline void skip_whitespace() { while (!is_end(s_itr_) && details::is_whitespace(*s_itr_)) @@ -2348,47 +2374,72 @@ namespace exprtk return (0 != mode); } - static inline bool comment_end(const char_t c0, const char_t c1, const int mode) + static inline bool comment_end(const char_t c0, const char_t c1, int& mode) { - return ( - ((1 == mode) && ('\n' == c0)) || - ((2 == mode) && ( '*' == c0) && ('/' == c1)) - ); + if ( + ((1 == mode) && ('\n' == c0)) || + ((2 == mode) && ( '*' == c0) && ('/' == c1)) + ) + { + mode = 0; + return true; + } + else + return false; } }; int mode = 0; int increment = 0; - if (is_end(s_itr_) || is_end((s_itr_ + 1))) + if (is_end(s_itr_)) return; else if (!test::comment_start(*s_itr_, *(s_itr_ + 1), mode, increment)) return; + details::char_cptr cmt_start = s_itr_; + s_itr_ += increment; - while (!is_end(s_itr_) && !test::comment_end(*s_itr_, *(s_itr_ + 1), mode)) + while (!is_end(s_itr_)) { - ++s_itr_; + if ((1 == mode) && test::comment_end(*s_itr_, 0, mode)) + { + ++s_itr_; + return; + } + + if ((2 == mode)) + { + if (!is_end((s_itr_ + 1)) && test::comment_end(*s_itr_, *(s_itr_ + 1), mode)) + { + s_itr_ += 2; + return; + } + } + + ++s_itr_; } - if (!is_end(s_itr_)) + if (2 == mode) { - s_itr_ += mode; - - skip_whitespace(); - skip_comments (); + token_t t; + t.set_error(token::e_error, cmt_start, cmt_start + mode, base_itr_); + token_list_.push_back(t); } #endif } inline void scan_token() { - skip_whitespace(); - skip_comments (); - - if (is_end(s_itr_)) + if (details::is_whitespace(*s_itr_)) + { + skip_whitespace(); + return; + } + else if (is_comment_start(s_itr_)) { + skip_comments(); return; } else if (details::is_operator_char(*s_itr_)) @@ -2502,7 +2553,7 @@ namespace exprtk inline void scan_symbol() { - const char_t* initial_itr = s_itr_; + details::char_cptr initial_itr = s_itr_; while (!is_end(s_itr_)) { @@ -2553,11 +2604,11 @@ namespace exprtk (15) .1234e-3 */ - const char_t* initial_itr = s_itr_; - bool dot_found = false; - bool e_found = false; - bool post_e_sign_found = false; - bool post_e_digit_found = false; + details::char_cptr initial_itr = s_itr_; + bool dot_found = false; + bool e_found = false; + bool post_e_sign_found = false; + bool post_e_digit_found = false; token_t t; while (!is_end(s_itr_)) @@ -2640,7 +2691,7 @@ namespace exprtk inline void scan_special_function() { - const char_t* initial_itr = s_itr_; + details::char_cptr initial_itr = s_itr_; token_t t; // $fdd(x,x,x) = at least 11 chars @@ -2676,7 +2727,7 @@ namespace exprtk #ifndef exprtk_disable_string_capabilities inline void scan_string() { - const char_t* initial_itr = s_itr_ + 1; + details::char_cptr initial_itr = s_itr_ + 1; token_t t; if (std::distance(s_itr_,s_end_) < 2) @@ -2714,7 +2765,7 @@ namespace exprtk Note: The following 'awkward' conditional is due to various broken msvc compilers. */ - #if _MSC_VER == 1600 + #if defined(_MSC_VER) && (_MSC_VER == 1600) const bool within_range = !is_end(s_itr_ + 2) && !is_end(s_itr_ + 3) ; #else @@ -2780,9 +2831,9 @@ namespace exprtk token_list_itr_t token_itr_; token_list_itr_t store_token_itr_; token_t eof_token_; - const char_t* base_itr_; - const char_t* s_itr_; - const char_t* s_end_; + details::char_cptr base_itr_; + details::char_cptr s_itr_; + details::char_cptr s_end_; friend class token_scanner; friend class token_modifier; @@ -3307,7 +3358,7 @@ namespace exprtk return true; } - // '- -' --> '-' + // '- -' --> '+' else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_sub)) { /* @@ -3577,7 +3628,6 @@ namespace exprtk add_invalid(lexer::token::e_string ,lexer::token::e_string ); add_invalid(lexer::token::e_number ,lexer::token::e_string ); add_invalid(lexer::token::e_string ,lexer::token::e_number ); - add_invalid(lexer::token::e_string ,lexer::token::e_ternary); add_invalid_set1(lexer::token::e_assign ); add_invalid_set1(lexer::token::e_shr ); add_invalid_set1(lexer::token::e_shl ); @@ -3696,7 +3746,7 @@ namespace exprtk case lexer::token::e_sub : return false; case lexer::token::e_colon : return false; case lexer::token::e_ternary : return false; - default : return true; + default : return true ; } } } @@ -3710,7 +3760,7 @@ namespace exprtk case lexer::token::e_eof : return false; case lexer::token::e_colon : return false; case lexer::token::e_ternary : return false; - default : return true; + default : return true ; } } else if (details::is_left_bracket(static_cast<char>(t))) @@ -4204,6 +4254,11 @@ namespace exprtk data_(reinterpret_cast<value_t*>(ts_.data)) {} + type_view(const type_store_t& ts) + : ts_(const_cast<type_store_t&>(ts)), + data_(reinterpret_cast<value_t*>(ts_.data)) + {} + inline std::size_t size() const { return ts_.size; @@ -5544,7 +5599,7 @@ namespace exprtk virtual std::string str () const = 0; - virtual const char_t* base() const = 0; + virtual char_cptr base() const = 0; virtual std::size_t size() const = 0; }; @@ -5587,7 +5642,7 @@ namespace exprtk return value_; } - const char_t* base() const + char_cptr base() const { return value_.data(); } @@ -5893,10 +5948,8 @@ namespace exprtk else return ((T(2) * arg1 <= (arg2 + arg0)) ? arg0 : arg2); - default : { - exprtk_debug(("trinary_node::value() - Error: Invalid operation\n")); - return std::numeric_limits<T>::quiet_NaN(); - } + default : exprtk_debug(("trinary_node::value() - Error: Invalid operation\n")); + return std::numeric_limits<T>::quiet_NaN(); } } @@ -7494,7 +7547,7 @@ namespace exprtk return ref(); } - const char_t* base() const + char_cptr base() const { return &(*value_)[0]; } @@ -7574,7 +7627,7 @@ namespace exprtk return (*value_); } - const char_t* base() const + char_cptr base() const { return &(*value_)[0]; } @@ -7652,7 +7705,7 @@ namespace exprtk return value_; } - const char_t* base() const + char_cptr base() const { return value_.data(); } @@ -7782,7 +7835,7 @@ namespace exprtk return value_; } - const char_t* base() const + char_cptr base() const { return &value_[0]; } @@ -7921,7 +7974,7 @@ namespace exprtk return value_; } - const char_t* base() const + char_cptr base() const { return &value_[0]; } @@ -8009,7 +8062,7 @@ namespace exprtk return str0_node_ptr_->str(); } - const char_t* base() const + char_cptr base() const { return str0_node_ptr_->base(); } @@ -8069,12 +8122,12 @@ namespace exprtk if (0 == str0_base_ptr_) return; - irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first); + irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first); - if (0 == range_ptr) + if (0 == range) return; - str0_range_ptr_ = &(range_ptr->range_ref()); + str0_range_ptr_ = &(range->range_ref()); } if (is_generally_string_node(binary_node<T>::branch_[1].first)) @@ -8084,12 +8137,12 @@ namespace exprtk if (0 == str1_base_ptr_) return; - irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first); + irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first); - if (0 == range_ptr) + if (0 == range) return; - str1_range_ptr_ = &(range_ptr->range_ref()); + str1_range_ptr_ = &(range->range_ref()); } initialised_ = str0_base_ptr_ && @@ -8123,11 +8176,11 @@ namespace exprtk const std::size_t size1 = range1.cache_size(); const std::size_t max_size = std::min(size0,size1); - char_t* s0 = const_cast<char_t*>(str0_base_ptr_->base() + str0_r0); - char_t* s1 = const_cast<char_t*>(str1_base_ptr_->base() + str1_r0); + char_ptr s0 = const_cast<char_ptr>(str0_base_ptr_->base() + str0_r0); + char_ptr s1 = const_cast<char_ptr>(str1_base_ptr_->base() + str1_r0); loop_unroll::details lud(max_size); - const char_t* upper_bound = s0 + lud.upper_bound; + char_cptr upper_bound = s0 + lud.upper_bound; while (s0 < upper_bound) { @@ -8285,13 +8338,13 @@ namespace exprtk struct asn_assignment { - static inline void execute(std::string& s, const char_t* data, const std::size_t size) + static inline void execute(std::string& s, char_cptr data, const std::size_t size) { s.assign(data,size); } }; struct asn_addassignment { - static inline void execute(std::string& s, const char_t* data, const std::size_t size) + static inline void execute(std::string& s, char_cptr data, const std::size_t size) { s.append(data,size); } }; @@ -8334,12 +8387,12 @@ namespace exprtk if (0 == str1_base_ptr_) return; - irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first); + irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first); - if (0 == range_ptr) + if (0 == range) return; - str1_range_ptr_ = &(range_ptr->range_ref()); + str1_range_ptr_ = &(range->range_ref()); } initialised_ = str0_base_ptr_ && @@ -8377,7 +8430,7 @@ namespace exprtk return str0_node_ptr_->str(); } - const char_t* base() const + char_cptr base() const { return str0_node_ptr_->base(); } @@ -8443,12 +8496,12 @@ namespace exprtk str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first); - irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first); + irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first); - if (0 == range_ptr) + if (0 == range) return; - str0_range_ptr_ = &(range_ptr->range_ref()); + str0_range_ptr_ = &(range->range_ref()); } if (is_generally_string_node(binary_node<T>::branch_[1].first)) @@ -8458,12 +8511,12 @@ namespace exprtk if (0 == str1_base_ptr_) return; - irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first); + irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first); - if (0 == range_ptr) + if (0 == range) return; - str1_range_ptr_ = &(range_ptr->range_ref()); + str1_range_ptr_ = &(range->range_ref()); } initialised_ = str0_base_ptr_ && @@ -8498,7 +8551,7 @@ namespace exprtk std::copy(str1_base_ptr_->base() + s1_r0, str1_base_ptr_->base() + s1_r0 + size, - const_cast<char_t*>(base() + s0_r0)); + const_cast<char_ptr>(base() + s0_r0)); } } @@ -8510,7 +8563,7 @@ namespace exprtk return str0_node_ptr_->str(); } - const char_t* base() const + char_cptr base() const { return str0_node_ptr_->base(); } @@ -8664,7 +8717,7 @@ namespace exprtk return value_; } - const char_t* base() const + char_cptr base() const { return &value_[0]; } @@ -8784,7 +8837,7 @@ namespace exprtk return value_; } - const char_t* base() const + char_cptr base() const { return &value_[0]; } @@ -8877,7 +8930,7 @@ namespace exprtk } else { - arg_list_.clear(); + arg_list_ .clear(); delete_branch_.clear(); return; } @@ -8918,7 +8971,7 @@ namespace exprtk return str_base_ptr_->str(); } - const char_t* base() const + char_cptr base() const { return str_base_ptr_->base(); } @@ -11443,7 +11496,7 @@ namespace exprtk return false; ts.size = sbn->size(); - ts.data = reinterpret_cast<void*>(const_cast<char_t*>(sbn->base())); + ts.data = reinterpret_cast<void*>(const_cast<char_ptr>(sbn->base())); ts.type = type_store_t::e_string; range_list_[i].data = ts.data; @@ -11464,7 +11517,7 @@ namespace exprtk ) { ts.size = rp.const_size(); - ts.data = static_cast<char_t*>(ts.data) + rp.n0_c.second; + ts.data = static_cast<char_ptr>(ts.data) + rp.n0_c.second; range_list_[i].range = reinterpret_cast<range_t*>(0); } else @@ -11546,10 +11599,10 @@ namespace exprtk ts.size = rp.cache_size(); #ifndef exprtk_disable_string_capabilities if (ts.type == type_store_t::e_string) - ts.data = const_cast<char_t*>(rdt.str_node->base()) + rp.cache.first; + ts.data = const_cast<char_ptr>(rdt.str_node->base()) + rp.cache.first; else #endif - ts.data = static_cast<char_t*>(rdt.data) + (rp.cache.first * rdt.type_size); + ts.data = static_cast<char_ptr>(rdt.data) + (rp.cache.first * rdt.type_size); } else return false; @@ -11629,7 +11682,7 @@ namespace exprtk return ret_string_; } - const char_t* base() const + char_cptr base() const { return &ret_string_[0]; } @@ -14965,12 +15018,12 @@ namespace exprtk if (0 == str0_base_ptr_) return; - irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first); + irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first); - if (0 == range_ptr) + if (0 == range) return; - str0_range_ptr_ = &(range_ptr->range_ref()); + str0_range_ptr_ = &(range->range_ref()); } if (is_generally_string_node(binary_node<T>::branch_[1].first)) @@ -14980,12 +15033,12 @@ namespace exprtk if (0 == str1_base_ptr_) return; - irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first); + irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first); - if (0 == range_ptr) + if (0 == range) return; - str1_range_ptr_ = &(range_ptr->range_ref()); + str1_range_ptr_ = &(range->range_ref()); } } @@ -15448,70 +15501,70 @@ namespace exprtk typename T1, typename T2> inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2) const { - return (new node_type(t1,t2)); + return (new node_type(t1, t2)); } template <typename node_type, typename T1, typename T2> inline expression_node<typename node_type::value_type>* allocate_cr(const T1& t1, T2& t2) const { - return (new node_type(t1,t2)); + return (new node_type(t1, t2)); } template <typename node_type, typename T1, typename T2> inline expression_node<typename node_type::value_type>* allocate_rc(T1& t1, const T2& t2) const { - return (new node_type(t1,t2)); + return (new node_type(t1, t2)); } template <typename node_type, typename T1, typename T2> inline expression_node<typename node_type::value_type>* allocate_rr(T1& t1, T2& t2) const { - return (new node_type(t1,t2)); + return (new node_type(t1, t2)); } template <typename node_type, typename T1, typename T2> inline expression_node<typename node_type::value_type>* allocate_tt(T1 t1, T2 t2) const { - return (new node_type(t1,t2)); + return (new node_type(t1, t2)); } template <typename node_type, typename T1, typename T2, typename T3> inline expression_node<typename node_type::value_type>* allocate_ttt(T1 t1, T2 t2, T3 t3) const { - return (new node_type(t1,t2,t3)); + return (new node_type(t1, t2, t3)); } template <typename node_type, typename T1, typename T2, typename T3, typename T4> inline expression_node<typename node_type::value_type>* allocate_tttt(T1 t1, T2 t2, T3 t3, T4 t4) const { - return (new node_type(t1,t2,t3,t4)); + return (new node_type(t1, t2, t3, t4)); } template <typename node_type, typename T1, typename T2, typename T3> inline expression_node<typename node_type::value_type>* allocate_rrr(T1& t1, T2& t2, T3& t3) const { - return (new node_type(t1,t2,t3)); + return (new node_type(t1, t2, t3)); } template <typename node_type, typename T1, typename T2, typename T3, typename T4> inline expression_node<typename node_type::value_type>* allocate_rrrr(T1& t1, T2& t2, T3& t3, T4& t4) const { - return (new node_type(t1,t2,t3,t4)); + return (new node_type(t1, t2, t3, t4)); } template <typename node_type, typename T1, typename T2, typename T3, typename T4, typename T5> inline expression_node<typename node_type::value_type>* allocate_rrrrr(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) const { - return (new node_type(t1,t2,t3,t4,t5)); + return (new node_type(t1, t2, t3, t4, t5)); } template <typename node_type, @@ -15519,7 +15572,7 @@ namespace exprtk inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2, const T3& t3) const { - return (new node_type(t1,t2,t3)); + return (new node_type(t1, t2, t3)); } template <typename node_type, @@ -15528,7 +15581,7 @@ namespace exprtk inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2, const T3& t3, const T4& t4) const { - return (new node_type(t1,t2,t3,t4)); + return (new node_type(t1, t2, t3, t4)); } template <typename node_type, @@ -15538,7 +15591,7 @@ namespace exprtk const T3& t3, const T4& t4, const T5& t5) const { - return (new node_type(t1,t2,t3,t4,t5)); + return (new node_type(t1, t2, t3, t4, t5)); } template <typename node_type, @@ -15548,7 +15601,7 @@ namespace exprtk const T3& t3, const T4& t4, const T5& t5, const T6& t6) const { - return (new node_type(t1,t2,t3,t4,t5,t6)); + return (new node_type(t1, t2, t3, t4, t5, t6)); } template <typename node_type, @@ -15560,7 +15613,7 @@ namespace exprtk const T5& t5, const T6& t6, const T7& t7) const { - return (new node_type(t1,t2,t3,t4,t5,t6,t7)); + return (new node_type(t1, t2, t3, t4, t5, t6, t7)); } template <typename node_type, @@ -15573,7 +15626,7 @@ namespace exprtk const T5& t5, const T6& t6, const T7& t7, const T8& t8) const { - return (new node_type(t1,t2,t3,t4,t5,t6,t7,t8)); + return (new node_type(t1, t2, t3, t4, t5, t6, t7, t8)); } template <typename node_type, @@ -15587,7 +15640,7 @@ namespace exprtk const T7& t7, const T8& t8, const T9& t9) const { - return (new node_type(t1,t2,t3,t4,t5,t6,t7,t8,t9)); + return (new node_type(t1, t2, t3, t4, t5, t6, t7, t8, t9)); } template <typename node_type, @@ -15602,14 +15655,14 @@ namespace exprtk const T7& t7, const T8& t8, const T9& t9, const T10& t10) const { - return (new node_type(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)); + return (new node_type(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10)); } template <typename node_type, typename T1, typename T2, typename T3> inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2, T3 t3) const { - return (new node_type(t1,t2,t3)); + return (new node_type(t1, t2, t3)); } template <typename node_type, @@ -15618,7 +15671,7 @@ namespace exprtk inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2, T3 t3, T4 t4) const { - return (new node_type(t1,t2,t3,t4)); + return (new node_type(t1, t2, t3, t4)); } template <typename node_type, @@ -15629,7 +15682,7 @@ namespace exprtk T3 t3, T4 t4, T5 t5) const { - return (new node_type(t1,t2,t3,t4,t5)); + return (new node_type(t1, t2, t3, t4, t5)); } template <typename node_type, @@ -15640,7 +15693,7 @@ namespace exprtk T3 t3, T4 t4, T5 t5, T6 t6) const { - return (new node_type(t1,t2,t3,t4,t5,t6)); + return (new node_type(t1, t2, t3, t4, t5, t6)); } template <typename node_type, @@ -15652,7 +15705,7 @@ namespace exprtk T5 t5, T6 t6, T7 t7) const { - return (new node_type(t1,t2,t3,t4,t5,t6,t7)); + return (new node_type(t1, t2, t3, t4, t5, t6, t7)); } template <typename T> @@ -15975,6 +16028,7 @@ namespace exprtk { public: + typedef T (*ff00_functor)(); typedef T (*ff01_functor)(T); typedef T (*ff02_functor)(T,T); typedef T (*ff03_functor)(T,T,T); @@ -15993,6 +16047,16 @@ namespace exprtk protected: + struct freefunc00 : public exprtk::ifunction<T> + { + using exprtk::ifunction<T>::operator(); + + freefunc00(ff00_functor ff) : exprtk::ifunction<T>(0), f(ff) {} + inline T operator() () + { return f(); } + ff00_functor f; + }; + struct freefunc01 : public exprtk::ifunction<T> { using exprtk::ifunction<T>::operator(); @@ -17021,11 +17085,11 @@ namespace exprtk inline bool add_function(const std::string& function_name, ff##NN##_functor function) \ { \ if (!valid()) \ - return false; \ - else if (!valid_symbol(function_name)) \ - return false; \ - else if (symbol_exists(function_name)) \ - return false; \ + { return false; } \ + if (!valid_symbol(function_name)) \ + { return false; } \ + if (symbol_exists(function_name)) \ + { return false; } \ \ exprtk::ifunction<T>* ifunc = new freefunc##NN(function); \ \ @@ -17034,14 +17098,14 @@ namespace exprtk return add_function(function_name,(*local_data().free_function_list_.back())); \ } \ - exprtk_define_freefunction(01) exprtk_define_freefunction(02) - exprtk_define_freefunction(03) exprtk_define_freefunction(04) - exprtk_define_freefunction(05) exprtk_define_freefunction(06) - exprtk_define_freefunction(07) exprtk_define_freefunction(08) - exprtk_define_freefunction(09) exprtk_define_freefunction(10) - exprtk_define_freefunction(11) exprtk_define_freefunction(12) - exprtk_define_freefunction(13) exprtk_define_freefunction(14) - exprtk_define_freefunction(15) + exprtk_define_freefunction(00) exprtk_define_freefunction(01) + exprtk_define_freefunction(02) exprtk_define_freefunction(03) + exprtk_define_freefunction(04) exprtk_define_freefunction(05) + exprtk_define_freefunction(06) exprtk_define_freefunction(07) + exprtk_define_freefunction(08) exprtk_define_freefunction(09) + exprtk_define_freefunction(10) exprtk_define_freefunction(11) + exprtk_define_freefunction(12) exprtk_define_freefunction(13) + exprtk_define_freefunction(14) exprtk_define_freefunction(15) #undef exprtk_define_freefunction @@ -17189,12 +17253,13 @@ namespace exprtk { return add_pi () && add_epsilon () && - add_infinity(); + add_infinity() ; } inline bool add_pi() { - static const T local_pi = T(details::numeric::constant::pi); + const typename details::numeric::details::number_type<T>::type num_type; + static const T local_pi = details::numeric::details::const_pi_impl<T>(num_type); return add_constant("pi",local_pi); } @@ -17542,7 +17607,7 @@ namespace exprtk size(0) {} - data_pack(void* ptr, data_type dt, std::size_t sz = 0) + data_pack(void* ptr, const data_type dt, const std::size_t sz = 0) : pointer(ptr), type(dt), size(sz) @@ -17657,6 +17722,13 @@ namespace exprtk control_block_->ref_count++; } + expression(const symbol_table<T>& symbol_table) + : control_block_(0) + { + set_expression(new details::null_node<T>()); + symbol_table_list_.push_back(symbol_table); + } + inline expression<T>& operator=(const expression<T>& e) { if (this != &e) @@ -17945,7 +18017,7 @@ namespace exprtk std::size_t column_no; }; - inline type make_error(error_mode mode, + inline type make_error(const error_mode mode, const std::string& diagnostic = "", const std::string& src_location = "") { @@ -17958,7 +18030,7 @@ namespace exprtk return t; } - inline type make_error(error_mode mode, + inline type make_error(const error_mode mode, const lexer::token& tk, const std::string& diagnostic = "", const std::string& src_location = "") @@ -18129,11 +18201,11 @@ namespace exprtk typedef typename expression<T>::symtab_list_t symbol_table_list_t; typedef details::vector_holder<T>* vector_holder_ptr; - typedef typename details::functor_t<T> functor_t; - typedef typename functor_t::qfunc_t quaternary_functor_t; - typedef typename functor_t::tfunc_t trinary_functor_t; - typedef typename functor_t::bfunc_t binary_functor_t; - typedef typename functor_t::ufunc_t unary_functor_t; + typedef typename details::functor_t<T> functor_t; + typedef typename functor_t::qfunc_t quaternary_functor_t; + typedef typename functor_t::tfunc_t trinary_functor_t; + typedef typename functor_t::bfunc_t binary_functor_t; + typedef typename functor_t::ufunc_t unary_functor_t; typedef details::operator_type operator_t; @@ -20410,6 +20482,7 @@ namespace exprtk static const std::string s_ilike = "ilike"; static const std::string s_and1 = "&"; static const std::string s_or1 = "|"; + static const std::string s_not = "not"; if (details::imatch(current_token().value,s_and)) { @@ -20474,6 +20547,10 @@ namespace exprtk current_state.set(e_level04, e_level04, details::e_ilike); break; } + else if (details::imatch(current_token().value,s_not)) + { + break; + } } break_loop = true; @@ -20953,7 +21030,7 @@ namespace exprtk } template <std::size_t MaxNumberofParameters> - inline std::size_t parse_base_function_call(expression_node_ptr (¶m_list)[MaxNumberofParameters]) + inline std::size_t parse_base_function_call(expression_node_ptr (¶m_list)[MaxNumberofParameters], const std::string& function_name = "") { std::fill_n(param_list, MaxNumberofParameters, reinterpret_cast<expression_node_ptr>(0)); @@ -20966,7 +21043,19 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR022 - Expected a '(' at start of function call, instead got: '" + current_token().value + "'", + "ERR022 - Expected a '(' at start of function call to '" + function_name + + "', instead got: '" + current_token().value + "'", + exprtk_error_location)); + + return 0; + } + + if (token_is(token_t::e_rbracket, e_hold)) + { + set_error( + make_error(parser_error::e_syntax, + current_token(), + "ERR023 - Expected at least one input parameter for function call '" + function_name + "'", exprtk_error_location)); return 0; @@ -20981,7 +21070,10 @@ namespace exprtk if (0 == param_list[param_index]) return 0; else if (token_is(token_t::e_rbracket)) + { + sd.delete_ptr = false; break; + } else if (token_is(token_t::e_comma)) continue; else @@ -20989,14 +21081,23 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR023 - Expected a ',' between function input parameters, instead got: '" + current_token().value + "'", + "ERR024 - Expected a ',' between function input parameters, instead got: '" + current_token().value + "'", exprtk_error_location)); return 0; } } - sd.delete_ptr = false; + if (sd.delete_ptr) + { + set_error( + make_error(parser_error::e_syntax, + current_token(), + "ERR025 - Invalid number of input parameters passed to function '" + function_name + "'", + exprtk_error_location)); + + return 0; + } return (param_index + 1); } @@ -21005,7 +21106,8 @@ namespace exprtk { typedef std::pair<base_ops_map_t::iterator,base_ops_map_t::iterator> map_range_t; - const std::string operation_name = current_token().value; + const std::string operation_name = current_token().value; + const token_t diagnostic_token = current_token(); map_range_t itr_range = base_ops_map_.equal_range(operation_name); @@ -21013,8 +21115,8 @@ namespace exprtk { set_error( make_error(parser_error::e_syntax, - current_token(), - "ERR024 - No entry found for base operation: " + operation_name, + diagnostic_token, + "ERR026 - No entry found for base operation: " + operation_name, exprtk_error_location)); return error_node(); @@ -21023,13 +21125,9 @@ namespace exprtk static const std::size_t MaxNumberofParameters = 4; expression_node_ptr param_list[MaxNumberofParameters] = {0}; - const std::size_t parameter_count = parse_base_function_call(param_list); + const std::size_t parameter_count = parse_base_function_call(param_list, operation_name); - if (0 == parameter_count) - { - return error_node(); - } - else if (parameter_count <= MaxNumberofParameters) + if ((parameter_count > 0) && (parameter_count <= MaxNumberofParameters)) { for (base_ops_map_t::iterator itr = itr_range.first; itr != itr_range.second; ++itr) { @@ -21059,13 +21157,13 @@ namespace exprtk for (std::size_t i = 0; i < MaxNumberofParameters; ++i) { - free_node(node_allocator_,param_list[i]); + free_node(node_allocator_, param_list[i]); } set_error( make_error(parser_error::e_syntax, - current_token(), - "ERR025 - Invalid number of parameters for call to function: '" + operation_name + "'", + diagnostic_token, + "ERR027 - Invalid number of input parameters for call to function: '" + operation_name + "'", exprtk_error_location)); return error_node(); @@ -21085,7 +21183,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR026 - Expected ',' between if-statement condition and consequent", + "ERR028 - Expected ',' between if-statement condition and consequent", exprtk_error_location)); result = false; } @@ -21094,7 +21192,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR027 - Failed to parse consequent for if-statement", + "ERR029 - Failed to parse consequent for if-statement", exprtk_error_location)); result = false; } @@ -21103,7 +21201,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR028 - Expected ',' between if-statement consequent and alternative", + "ERR030 - Expected ',' between if-statement consequent and alternative", exprtk_error_location)); result = false; } @@ -21112,7 +21210,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR029 - Failed to parse alternative for if-statement", + "ERR031 - Failed to parse alternative for if-statement", exprtk_error_location)); result = false; } @@ -21121,7 +21219,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR030 - Expected ')' at the end of if-statement", + "ERR032 - Expected ')' at the end of if-statement", exprtk_error_location)); result = false; } @@ -21143,7 +21241,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR031 - Return types of ternary if-statement differ", + "ERR033 - Return types of ternary if-statement differ", exprtk_error_location)); result = false; @@ -21178,7 +21276,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR032 - Failed to parse body of consequent for if-statement", + "ERR034 - Failed to parse body of consequent for if-statement", exprtk_error_location)); result = false; @@ -21201,7 +21299,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR033 - Expected ';' at the end of the consequent for if-statement", + "ERR035 - Expected ';' at the end of the consequent for if-statement", exprtk_error_location)); result = false; @@ -21212,7 +21310,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR034 - Failed to parse body of consequent for if-statement", + "ERR036 - Failed to parse body of consequent for if-statement", exprtk_error_location)); result = false; @@ -21232,7 +21330,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR035 - Failed to parse body of the 'else' for if-statement", + "ERR037 - Failed to parse body of the 'else' for if-statement", exprtk_error_location)); result = false; @@ -21245,7 +21343,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR036 - Failed to parse body of if-else statement", + "ERR038 - Failed to parse body of if-else statement", exprtk_error_location)); result = false; @@ -21258,7 +21356,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR037 - Expected ';' at the end of the 'else-if' for the if-statement", + "ERR039 - Expected ';' at the end of the 'else-if' for the if-statement", exprtk_error_location)); result = false; @@ -21269,7 +21367,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR038 - Failed to parse body of the 'else' for if-statement", + "ERR040 - Failed to parse body of the 'else' for if-statement", exprtk_error_location)); result = false; @@ -21288,13 +21386,13 @@ namespace exprtk if (consq_is_str && alter_is_str) { return expression_generator_ - .conditional_string(condition,consequent,alternative); + .conditional_string(condition, consequent, alternative); } set_error( make_error(parser_error::e_syntax, current_token(), - "ERR039 - Return types of ternary if-statement differ", + "ERR041 - Return types of ternary if-statement differ", exprtk_error_location)); result = false; @@ -21304,15 +21402,15 @@ namespace exprtk if (!result) { - free_node(node_allocator_, condition); - free_node(node_allocator_, consequent); - free_node(node_allocator_,alternative); + free_node(node_allocator_, condition); + free_node(node_allocator_, consequent); + free_node(node_allocator_, alternative); return error_node(); } else return expression_generator_ - .conditional(condition,consequent,alternative); + .conditional(condition, consequent, alternative); } inline expression_node_ptr parse_conditional_statement() @@ -21326,7 +21424,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR040 - Expected '(' at start of if-statement, instead got: '" + current_token().value + "'", + "ERR042 - Expected '(' at start of if-statement, instead got: '" + current_token().value + "'", exprtk_error_location)); return error_node(); @@ -21336,7 +21434,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR041 - Failed to parse condition for if-statement", + "ERR043 - Failed to parse condition for if-statement", exprtk_error_location)); return error_node(); @@ -21368,7 +21466,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR042 - Invalid if-statement", + "ERR044 - Invalid if-statement", exprtk_error_location)); free_node(node_allocator_,condition); @@ -21389,7 +21487,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR043 - Encountered invalid condition branch for ternary if-statement", + "ERR045 - Encountered invalid condition branch for ternary if-statement", exprtk_error_location)); return error_node(); @@ -21399,7 +21497,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR044 - Expected '?' after condition of ternary if-statement", + "ERR046 - Expected '?' after condition of ternary if-statement", exprtk_error_location)); result = false; @@ -21409,7 +21507,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR045 - Failed to parse consequent for ternary if-statement", + "ERR047 - Failed to parse consequent for ternary if-statement", exprtk_error_location)); result = false; @@ -21419,7 +21517,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR046 - Expected ':' between ternary if-statement consequent and alternative", + "ERR048 - Expected ':' between ternary if-statement consequent and alternative", exprtk_error_location)); result = false; @@ -21429,7 +21527,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR047 - Failed to parse alternative for ternary if-statement", + "ERR049 - Failed to parse alternative for ternary if-statement", exprtk_error_location)); result = false; @@ -21452,7 +21550,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR048 - Return types of ternary if-statement differ", + "ERR050 - Return types of ternary if-statement differ", exprtk_error_location)); result = false; @@ -21489,7 +21587,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR049 - Expected '(' at start of while-loop condition statement", + "ERR051 - Expected '(' at start of while-loop condition statement", exprtk_error_location)); return error_node(); @@ -21499,7 +21597,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR050 - Failed to parse condition for while-loop", + "ERR052 - Failed to parse condition for while-loop", exprtk_error_location)); return error_node(); @@ -21509,7 +21607,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR051 - Expected ')' at end of while-loop condition statement", + "ERR053 - Expected ')' at end of while-loop condition statement", exprtk_error_location)); result = false; @@ -21524,7 +21622,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR052 - Failed to parse body of while-loop")); + "ERR054 - Failed to parse body of while-loop")); result = false; } else if (0 == (result_node = expression_generator_.while_loop(condition, @@ -21534,7 +21632,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR053 - Failed to synthesize while-loop", + "ERR055 - Failed to synthesize while-loop", exprtk_error_location)); result = false; @@ -21543,9 +21641,9 @@ namespace exprtk if (!result) { - free_node(node_allocator_, branch); - free_node(node_allocator_, condition); - free_node(node_allocator_,result_node); + free_node(node_allocator_, branch); + free_node(node_allocator_, condition); + free_node(node_allocator_, result_node); brkcnt_list_.pop_front(); @@ -21610,7 +21708,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR054 - Expected '" + token_t::to_str(seperator) + "' in body of repeat until loop", + "ERR056 - Expected '" + token_t::to_str(seperator) + "' in body of repeat until loop", exprtk_error_location)); return error_node(); @@ -21634,7 +21732,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR055 - Failed to parse body of repeat until loop", + "ERR057 - Failed to parse body of repeat until loop", exprtk_error_location)); return error_node(); @@ -21648,7 +21746,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR056 - Expected '(' before condition statement of repeat until loop", + "ERR058 - Expected '(' before condition statement of repeat until loop", exprtk_error_location)); free_node(node_allocator_,branch); @@ -21662,7 +21760,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR057 - Failed to parse condition for repeat until loop", + "ERR059 - Failed to parse condition for repeat until loop", exprtk_error_location)); free_node(node_allocator_,branch); @@ -21674,7 +21772,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR058 - Expected ')' after condition of repeat until loop", + "ERR060 - Expected ')' after condition of repeat until loop", exprtk_error_location)); free_node(node_allocator_, branch); @@ -21695,7 +21793,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR059 - Failed to synthesize repeat until loop", + "ERR061 - Failed to synthesize repeat until loop", exprtk_error_location)); free_node(node_allocator_,condition); @@ -21731,7 +21829,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR060 - Expected '(' at start of for-loop", + "ERR062 - Expected '(' at start of for-loop", exprtk_error_location)); return error_node(); @@ -21751,7 +21849,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR061 - Expected a variable at the start of initialiser section of for-loop", + "ERR063 - Expected a variable at the start of initialiser section of for-loop", exprtk_error_location)); return error_node(); @@ -21761,7 +21859,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR062 - Expected variable assignment of initialiser section of for-loop", + "ERR064 - Expected variable assignment of initialiser section of for-loop", exprtk_error_location)); return error_node(); @@ -21776,7 +21874,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR063 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration", + "ERR065 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration", exprtk_error_location)); return error_node(); @@ -21808,7 +21906,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR064 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM", + "ERR066 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM", exprtk_error_location)); sem_.free_element(nse); @@ -21830,7 +21928,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR065 - Failed to parse initialiser of for-loop", + "ERR067 - Failed to parse initialiser of for-loop", exprtk_error_location)); result = false; @@ -21840,7 +21938,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR066 - Expected ';' after initialiser of for-loop", + "ERR068 - Expected ';' after initialiser of for-loop", exprtk_error_location)); result = false; @@ -21854,7 +21952,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR067 - Failed to parse condition of for-loop", + "ERR069 - Failed to parse condition of for-loop", exprtk_error_location)); result = false; @@ -21864,7 +21962,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR068 - Expected ';' after condition section of for-loop", + "ERR070 - Expected ';' after condition section of for-loop", exprtk_error_location)); result = false; @@ -21878,7 +21976,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR069 - Failed to parse incrementor of for-loop", + "ERR071 - Failed to parse incrementor of for-loop", exprtk_error_location)); result = false; @@ -21888,7 +21986,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR070 - Expected ')' after incrementor section of for-loop", + "ERR072 - Expected ')' after incrementor section of for-loop", exprtk_error_location)); result = false; @@ -21904,7 +22002,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR071 - Failed to parse body of for-loop", + "ERR073 - Failed to parse body of for-loop", exprtk_error_location)); result = false; @@ -21956,7 +22054,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR072 - Expected keyword 'switch'", + "ERR074 - Expected keyword 'switch'", exprtk_error_location)); return error_node(); @@ -21971,7 +22069,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR073 - Expected '{' for call to switch statement", + "ERR075 - Expected '{' for call to switch statement", exprtk_error_location)); return error_node(); @@ -21984,7 +22082,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR074 - Expected either a 'case' or 'default' statement", + "ERR076 - Expected either a 'case' or 'default' statement", exprtk_error_location)); return error_node(); @@ -22001,7 +22099,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR075 - Expected ':' for case of switch statement", + "ERR077 - Expected ':' for case of switch statement", exprtk_error_location)); return error_node(); @@ -22016,7 +22114,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR076 - Expected ';' at end of case for switch statement", + "ERR078 - Expected ';' at end of case for switch statement", exprtk_error_location)); return error_node(); @@ -22042,7 +22140,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR077 - Expected ':' for default of switch statement", + "ERR079 - Expected ':' for default of switch statement", exprtk_error_location)); return error_node(); @@ -22064,7 +22162,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR078 - Expected ';' at end of default for switch statement", + "ERR080 - Expected ';' at end of default for switch statement", exprtk_error_location)); return error_node(); @@ -22080,7 +22178,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR079 - Expected '}' at end of switch statement", + "ERR081 - Expected '}' at end of switch statement", exprtk_error_location)); return error_node(); @@ -22103,7 +22201,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR080 - Expected token '[*]'", + "ERR082 - Expected token '[*]'", exprtk_error_location)); return error_node(); @@ -22118,7 +22216,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR081 - Expected '{' for call to [*] statement", + "ERR083 - Expected '{' for call to [*] statement", exprtk_error_location)); return error_node(); @@ -22131,7 +22229,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR082 - Expected a 'case' statement for multi-switch", + "ERR084 - Expected a 'case' statement for multi-switch", exprtk_error_location)); return error_node(); @@ -22149,7 +22247,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR083 - Expected ':' for case of [*] statement", + "ERR085 - Expected ':' for case of [*] statement", exprtk_error_location)); return error_node(); @@ -22165,7 +22263,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR084 - Expected ';' at end of case for [*] statement", + "ERR086 - Expected ';' at end of case for [*] statement", exprtk_error_location)); return error_node(); @@ -22194,7 +22292,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR085 - Expected '}' at end of [*] statement", + "ERR087 - Expected '}' at end of [*] statement", exprtk_error_location)); return error_node(); @@ -22224,19 +22322,19 @@ namespace exprtk { return parse_multi_switch_statement(); } - else if (details::imatch(symbol,"avg" )) opt_type = details::e_avg ; - else if (details::imatch(symbol,"mand")) opt_type = details::e_mand; - else if (details::imatch(symbol,"max" )) opt_type = details::e_max ; - else if (details::imatch(symbol,"min" )) opt_type = details::e_min ; - else if (details::imatch(symbol,"mor" )) opt_type = details::e_mor ; - else if (details::imatch(symbol,"mul" )) opt_type = details::e_prod; - else if (details::imatch(symbol,"sum" )) opt_type = details::e_sum ; + else if (details::imatch(symbol, "avg" )) opt_type = details::e_avg ; + else if (details::imatch(symbol, "mand")) opt_type = details::e_mand; + else if (details::imatch(symbol, "max" )) opt_type = details::e_max ; + else if (details::imatch(symbol, "min" )) opt_type = details::e_min ; + else if (details::imatch(symbol, "mor" )) opt_type = details::e_mor ; + else if (details::imatch(symbol, "mul" )) opt_type = details::e_prod; + else if (details::imatch(symbol, "sum" )) opt_type = details::e_sum ; else { set_error( make_error(parser_error::e_syntax, current_token(), - "ERR086 - Unsupported vararg function: " + symbol, + "ERR088 - Unsupported vararg function: " + symbol, exprtk_error_location)); return error_node(); @@ -22253,7 +22351,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR087 - Expected '(' for call to vararg function: " + symbol, + "ERR089 - Expected '(' for call to vararg function: " + symbol, exprtk_error_location)); return error_node(); @@ -22275,7 +22373,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR088 - Expected ',' for call to vararg function: " + symbol, + "ERR090 - Expected ',' for call to vararg function: " + symbol, exprtk_error_location)); return error_node(); @@ -22296,7 +22394,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR089 - Expected '[' as start of string range definition", + "ERR091 - Expected '[' as start of string range definition", exprtk_error_location)); free_node(node_allocator_,expression); @@ -22324,7 +22422,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR090 - Failed to generate string range node", + "ERR092 - Failed to generate string range node", exprtk_error_location)); free_node(node_allocator_,expression); @@ -22460,7 +22558,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR091 - Expected '" + token_t::to_str(close_bracket) + "' for call to multi-sequence" + + "ERR093 - Expected '" + token_t::to_str(close_bracket) + "' for call to multi-sequence" + ((!source.empty()) ? std::string(" section of " + source): ""), exprtk_error_location)); @@ -22507,7 +22605,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR092 - Expected '" + details::to_str(seperator) + "' for call to multi-sequence section of " + source, + "ERR094 - Expected '" + details::to_str(seperator) + "' for call to multi-sequence section of " + source, exprtk_error_location)); return error_node(); @@ -22541,7 +22639,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR093 - Expected '[' for start of range", + "ERR095 - Expected '[' for start of range", exprtk_error_location)); return false; @@ -22562,7 +22660,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR094 - Failed parse begin section of range", + "ERR096 - Failed parse begin section of range", exprtk_error_location)); return false; @@ -22586,7 +22684,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR095 - Range lower bound less than zero! Constraint: r0 >= 0", + "ERR097 - Range lower bound less than zero! Constraint: r0 >= 0", exprtk_error_location)); return false; @@ -22603,7 +22701,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR096 - Expected ':' for break in range", + "ERR098 - Expected ':' for break in range", exprtk_error_location)); rp.free(); @@ -22626,7 +22724,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR097 - Failed parse end section of range", + "ERR099 - Failed parse end section of range", exprtk_error_location)); rp.free(); @@ -22652,7 +22750,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR098 - Range upper bound less than zero! Constraint: r1 >= 0", + "ERR100 - Range upper bound less than zero! Constraint: r1 >= 0", exprtk_error_location)); return false; @@ -22669,7 +22767,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR099 - Expected ']' for start of range", + "ERR101 - Expected ']' for start of range", exprtk_error_location)); rp.free(); @@ -22690,7 +22788,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR100 - Invalid range, Constraint: r0 <= r1", + "ERR102 - Invalid range, Constraint: r0 <= r1", exprtk_error_location)); return false; @@ -22731,7 +22829,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR101 - Unknown string symbol", + "ERR103 - Unknown string symbol", exprtk_error_location)); return error_node(); @@ -22845,7 +22943,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR102 - Overflow in range for string: '" + const_str + "'[" + + "ERR104 - Overflow in range for string: '" + const_str + "'[" + (rp.n0_c.first ? details::to_str(static_cast<int>(rp.n0_c.second)) : "?") + ":" + (rp.n1_c.first ? details::to_str(static_cast<int>(rp.n1_c.second)) : "?") + "]", exprtk_error_location)); @@ -22889,7 +22987,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR103 - Symbol '" + symbol+ " not a vector", + "ERR105 - Symbol '" + symbol+ " not a vector", exprtk_error_location)); return error_node(); @@ -22915,7 +23013,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR104 - Failed to parse index for vector: '" + symbol + "'", + "ERR106 - Failed to parse index for vector: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -22925,7 +23023,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR105 - Expected ']' for index of vector: '" + symbol + "'", + "ERR107 - Expected ']' for index of vector: '" + symbol + "'", exprtk_error_location)); free_node(node_allocator_,index_expr); @@ -22944,7 +23042,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR106 - Index of " + details::to_str(index) + " out of range for " + "ERR108 - Index of " + details::to_str(index) + " out of range for " "vector '" + symbol + "' of size " + details::to_str(vec_size), exprtk_error_location)); @@ -22976,7 +23074,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR107 - Zero parameter call to vararg function: " + "ERR109 - Zero parameter call to vararg function: " + vararg_function_name + " not allowed", exprtk_error_location)); @@ -23001,7 +23099,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR108 - Expected ',' for call to vararg function: " + "ERR110 - Expected ',' for call to vararg function: " + vararg_function_name, exprtk_error_location)); @@ -23015,7 +23113,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR109 - Zero parameter call to vararg function: " + "ERR111 - Zero parameter call to vararg function: " + vararg_function_name + " not allowed", exprtk_error_location)); @@ -23027,7 +23125,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR110 - Invalid number of parameters to call to vararg function: " + "ERR112 - Invalid number of parameters to call to vararg function: " + vararg_function_name + ", require at least " + details::to_str(static_cast<int>(vararg_function->min_num_args())) + " parameters", exprtk_error_location)); @@ -23039,7 +23137,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR111 - Invalid number of parameters to call to vararg function: " + "ERR113 - Invalid number of parameters to call to vararg function: " + vararg_function_name + ", require no more than " + details::to_str(static_cast<int>(vararg_function->max_num_args())) + " parameters", exprtk_error_location)); @@ -23102,7 +23200,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, parser_.current_token(), - "ERR112 - Failed parameter type check for function '" + function_name_ + "', " + "ERR114 - Failed parameter type check for function '" + function_name_ + "', " "Expected '" + param_seq_list_[0] + "' call set: '" + param_seq +"'", exprtk_error_location)); } @@ -23123,7 +23221,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, parser_.current_token(), - "ERR113 - Failed parameter type check for function '" + function_name_ + "', " + "ERR115 - Failed parameter type check for function '" + function_name_ + "', " "Best match: '" + param_seq_list_[max_diff_index] + "' call set: '" + param_seq +"'", exprtk_error_location)); } @@ -23208,7 +23306,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, parser_.current_token(), - "ERR114 - Invalid parameter sequence of '" + err_param_seq + + "ERR116 - Invalid parameter sequence of '" + err_param_seq + "' for function: " + function_name_, exprtk_error_location)); @@ -23230,7 +23328,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, parser_.current_token(), - "ERR115 - Invalid parameter sequence of '" + err_param_seq + + "ERR117 - Invalid parameter sequence of '" + err_param_seq + "' for function: " + function_name_, exprtk_error_location)); return; @@ -23264,7 +23362,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR116 - Type checker instantiation failure for generic function: " + function_name, + "ERR118 - Type checker instantiation failure for generic function: " + function_name, exprtk_error_location)); return error_node(); @@ -23279,7 +23377,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR117 - Mismatch in zero parameter condition for generic function: " + "ERR119 - Mismatch in zero parameter condition for generic function: " + function_name, exprtk_error_location)); @@ -23298,7 +23396,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR118 - Zero parameter call to generic function: " + "ERR120 - Zero parameter call to generic function: " + function_name + " not allowed", exprtk_error_location)); @@ -23330,7 +23428,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR119 - Expected ',' for call to generic function: " + function_name, + "ERR121 - Expected ',' for call to generic function: " + function_name, exprtk_error_location)); return error_node(); @@ -23347,7 +23445,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR120 - Zero parameter call to generic function: " + "ERR122 - Zero parameter call to generic function: " + function_name + " not allowed", exprtk_error_location)); @@ -23364,7 +23462,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR121 - Expected ',' for call to generic function: " + function_name, + "ERR123 - Expected ',' for call to generic function: " + function_name, exprtk_error_location)); return error_node(); @@ -23432,7 +23530,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR122 - Expected ',' for call to string function: " + function_name, + "ERR124 - Expected ',' for call to string function: " + function_name, exprtk_error_location)); return error_node(); @@ -23448,7 +23546,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR123 - Expected ',' for call to string function: " + function_name, + "ERR125 - Expected ',' for call to string function: " + function_name, exprtk_error_location)); return error_node(); @@ -23472,7 +23570,7 @@ namespace exprtk template <typename Type, std::size_t NumberOfParameters> struct parse_special_function_impl { - static inline expression_node_ptr process(parser<Type>& p,const details::operator_type opt_type) + static inline expression_node_ptr process(parser<Type>& p,const details::operator_type opt_type, const std::string& sf_name) { expression_node_ptr branch[NumberOfParameters]; expression_node_ptr result = error_node(); @@ -23488,7 +23586,7 @@ namespace exprtk p.set_error( make_error(parser_error::e_syntax, p.current_token(), - "ERR124 - Expected '(' for special function", + "ERR126 - Expected '(' for special function '" + sf_name + "'", exprtk_error_location)); return error_node(); @@ -23509,7 +23607,7 @@ namespace exprtk p.set_error( make_error(parser_error::e_syntax, p.current_token(), - "ERR125 - Expected ',' before next parameter of special function", + "ERR127 - Expected ',' before next parameter of special function '" + sf_name + "'", exprtk_error_location)); return p.error_node(); @@ -23518,7 +23616,15 @@ namespace exprtk } if (!p.token_is(token_t::e_rbracket)) + { + p.set_error( + make_error(parser_error::e_syntax, + p.current_token(), + "ERR128 - Invalid number of parameters for special function '" + sf_name + "'", + exprtk_error_location)); + return p.error_node(); + } else result = p.expression_generator_.special_function(opt_type,branch); @@ -23530,30 +23636,32 @@ namespace exprtk inline expression_node_ptr parse_special_function() { + const std::string sf_name = current_token().value; + // Expect: $fDD(expr0,expr1,expr2) or $fDD(expr0,expr1,expr2,expr3) if ( - !details::is_digit(current_token().value[2]) || - !details::is_digit(current_token().value[3]) + !details::is_digit(sf_name[2]) || + !details::is_digit(sf_name[3]) ) { set_error( make_error(parser_error::e_token, current_token(), - "ERR126 - Invalid special function[1]: " + current_token().value, + "ERR129 - Invalid special function[1]: " + sf_name, exprtk_error_location)); return error_node(); } - const int id = (current_token().value[2] - '0') * 10 + - (current_token().value[3] - '0'); + const int id = (sf_name[2] - '0') * 10 + + (sf_name[3] - '0'); if (id >= details::e_sffinal) { set_error( make_error(parser_error::e_token, current_token(), - "ERR127 - Invalid special function[2]: " + current_token().value, + "ERR130 - Invalid special function[2]: " + sf_name, exprtk_error_location)); return error_node(); @@ -23565,8 +23673,8 @@ namespace exprtk switch (NumberOfParameters) { - case 3 : return parse_special_function_impl<T,3>::process((*this),opt_type); - case 4 : return parse_special_function_impl<T,4>::process((*this),opt_type); + case 3 : return parse_special_function_impl<T,3>::process((*this), opt_type, sf_name); + case 4 : return parse_special_function_impl<T,4>::process((*this), opt_type, sf_name); default : return error_node(); } } @@ -23585,7 +23693,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR128 - Break call within a break call is not allowed", + "ERR131 - Break call within a break call is not allowed", exprtk_error_location)); return error_node(); @@ -23608,7 +23716,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR129 - Failed to parse return expression for 'break' statement", + "ERR132 - Failed to parse return expression for 'break' statement", exprtk_error_location)); return error_node(); @@ -23618,7 +23726,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR130 - Expected ']' at the completion of break's return expression", + "ERR133 - Expected ']' at the completion of break's return expression", exprtk_error_location)); free_node(node_allocator_,return_expr); @@ -23636,7 +23744,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR131 - Invalid use of 'break', allowed only in the scope of a loop", + "ERR134 - Invalid use of 'break', allowed only in the scope of a loop", exprtk_error_location)); } @@ -23659,7 +23767,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR132 - Invalid use of 'continue', allowed only in the scope of a loop", + "ERR135 - Invalid use of 'continue', allowed only in the scope of a loop", exprtk_error_location)); return error_node(); @@ -23676,7 +23784,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR133 - Expected '[' as part of vector size definition", + "ERR136 - Expected '[' as part of vector size definition", exprtk_error_location)); return error_node(); @@ -23686,7 +23794,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR134 - Failed to determine size of vector '" + vec_name + "'", + "ERR137 - Failed to determine size of vector '" + vec_name + "'", exprtk_error_location)); return error_node(); @@ -23698,7 +23806,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR135 - Expected a literal number as size of vector '" + vec_name + "'", + "ERR138 - Expected a literal number as size of vector '" + vec_name + "'", exprtk_error_location)); return error_node(); @@ -23717,7 +23825,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR136 - Invalid vector size. Must be an integer greater than zero, size: " + + "ERR139 - Invalid vector size. Must be an integer greater than zero, size: " + details::to_str(details::numeric::to_int32(vector_size)), exprtk_error_location)); @@ -23737,7 +23845,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR137 - Expected ']' as part of vector size definition", + "ERR140 - Expected ']' as part of vector size definition", exprtk_error_location)); return error_node(); @@ -23749,7 +23857,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR138 - Expected ':=' as part of vector definition", + "ERR141 - Expected ':=' as part of vector definition", exprtk_error_location)); return error_node(); @@ -23763,7 +23871,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR139 - Failed to parse single vector initialiser", + "ERR142 - Failed to parse single vector initialiser", exprtk_error_location)); return error_node(); @@ -23776,7 +23884,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR140 - Expected ']' to close single value vector initialiser", + "ERR143 - Expected ']' to close single value vector initialiser", exprtk_error_location)); return error_node(); @@ -23823,7 +23931,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR141 - Expected '{' as part of vector initialiser list", + "ERR144 - Expected '{' as part of vector initialiser list", exprtk_error_location)); return error_node(); @@ -23843,7 +23951,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR142 - Expected '{' as part of vector initialiser list", + "ERR145 - Expected '{' as part of vector initialiser list", exprtk_error_location)); return error_node(); @@ -23861,7 +23969,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR143 - Expected ',' between vector initialisers", + "ERR146 - Expected ',' between vector initialisers", exprtk_error_location)); return error_node(); @@ -23883,7 +23991,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR144 - Expected ';' at end of vector definition", + "ERR147 - Expected ';' at end of vector definition", exprtk_error_location)); return error_node(); @@ -23895,7 +24003,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR145 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'", + "ERR148 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'", exprtk_error_location)); return error_node(); @@ -23915,7 +24023,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR146 - Illegal redefinition of local vector: '" + vec_name + "'", + "ERR149 - Illegal redefinition of local vector: '" + vec_name + "'", exprtk_error_location)); return error_node(); @@ -23949,7 +24057,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR147 - Failed to add new local vector '" + vec_name + "' to SEM", + "ERR150 - Failed to add new local vector '" + vec_name + "' to SEM", exprtk_error_location)); sem_.free_element(nse); @@ -24004,7 +24112,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR148 - Illegal redefinition of local variable: '" + str_name + "'", + "ERR151 - Illegal redefinition of local variable: '" + str_name + "'", exprtk_error_location)); free_node(node_allocator_,initialisation_expression); @@ -24036,7 +24144,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR149 - Failed to add new local string variable '" + str_name + "' to SEM", + "ERR152 - Failed to add new local string variable '" + str_name + "' to SEM", exprtk_error_location)); free_node(node_allocator_,initialisation_expression); @@ -24082,7 +24190,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR150 - Illegal variable definition", + "ERR153 - Illegal variable definition", exprtk_error_location)); return error_node(); @@ -24103,7 +24211,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR151 - Expected a symbol for variable definition", + "ERR154 - Expected a symbol for variable definition", exprtk_error_location)); return error_node(); @@ -24113,7 +24221,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR152 - Illegal redefinition of reserved keyword: '" + var_name + "'", + "ERR155 - Illegal redefinition of reserved keyword: '" + var_name + "'", exprtk_error_location)); return error_node(); @@ -24123,7 +24231,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR153 - Illegal redefinition of variable '" + var_name + "'", + "ERR156 - Illegal redefinition of variable '" + var_name + "'", exprtk_error_location)); return error_node(); @@ -24133,7 +24241,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR154 - Illegal redefinition of local variable: '" + var_name + "'", + "ERR157 - Illegal redefinition of local variable: '" + var_name + "'", exprtk_error_location)); return error_node(); @@ -24153,7 +24261,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR155 - Failed to parse initialisation expression", + "ERR158 - Failed to parse initialisation expression", exprtk_error_location)); return error_node(); @@ -24171,7 +24279,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR156 - Expected ';' after variable definition", + "ERR159 - Expected ';' after variable definition", exprtk_error_location)); free_node(node_allocator_,initialisation_expression); @@ -24199,7 +24307,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR157 - Illegal redefinition of local variable: '" + var_name + "'", + "ERR160 - Illegal redefinition of local variable: '" + var_name + "'", exprtk_error_location)); free_node(node_allocator_, initialisation_expression); @@ -24231,7 +24339,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR158 - Failed to add new local variable '" + var_name + "' to SEM", + "ERR161 - Failed to add new local variable '" + var_name + "' to SEM", exprtk_error_location)); free_node(node_allocator_, initialisation_expression); @@ -24268,7 +24376,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR159 - Expected a '{}' for uninitialised var definition", + "ERR162 - Expected a '{}' for uninitialised var definition", exprtk_error_location)); return error_node(); @@ -24278,7 +24386,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR160 - Expected ';' after uninitialised variable definition", + "ERR163 - Expected ';' after uninitialised variable definition", exprtk_error_location)); return error_node(); @@ -24295,7 +24403,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR161 - Illegal redefinition of local variable: '" + var_name + "'", + "ERR164 - Illegal redefinition of local variable: '" + var_name + "'", exprtk_error_location)); return error_node(); @@ -24325,7 +24433,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR162 - Failed to add new local variable '" + var_name + "' to SEM", + "ERR165 - Failed to add new local variable '" + var_name + "' to SEM", exprtk_error_location)); sem_.free_element(nse); @@ -24358,7 +24466,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR163 - Expected '(' at start of swap statement", + "ERR166 - Expected '(' at start of swap statement", exprtk_error_location)); return error_node(); @@ -24377,7 +24485,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR164 - Expected a symbol for variable or vector element definition", + "ERR167 - Expected a symbol for variable or vector element definition", exprtk_error_location)); return error_node(); @@ -24389,7 +24497,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR165 - First parameter to swap is an invalid vector element: '" + var0_name + "'", + "ERR168 - First parameter to swap is an invalid vector element: '" + var0_name + "'", exprtk_error_location)); return error_node(); @@ -24422,7 +24530,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR166 - First parameter to swap is an invalid variable: '" + var0_name + "'", + "ERR169 - First parameter to swap is an invalid variable: '" + var0_name + "'", exprtk_error_location)); return error_node(); @@ -24436,7 +24544,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR167 - Expected ',' between parameters to swap", + "ERR170 - Expected ',' between parameters to swap", exprtk_error_location)); if (variable0_generated) @@ -24454,7 +24562,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR168 - Expected a symbol for variable or vector element definition", + "ERR171 - Expected a symbol for variable or vector element definition", exprtk_error_location)); if (variable0_generated) @@ -24471,7 +24579,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR169 - Second parameter to swap is an invalid vector element: '" + var1_name + "'", + "ERR172 - Second parameter to swap is an invalid vector element: '" + var1_name + "'", exprtk_error_location)); if (variable0_generated) @@ -24509,7 +24617,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR170 - Second parameter to swap is an invalid variable: '" + var1_name + "'", + "ERR173 - Second parameter to swap is an invalid variable: '" + var1_name + "'", exprtk_error_location)); if (variable0_generated) @@ -24528,7 +24636,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR171 - Expected ')' at end of swap statement", + "ERR174 - Expected ')' at end of swap statement", exprtk_error_location)); if (variable0_generated) @@ -24585,7 +24693,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR172 - Return call within a return call is not allowed", + "ERR175 - Return call within a return call is not allowed", exprtk_error_location)); return error_node(); @@ -24609,7 +24717,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR173 - Expected '[' at start of return statement", + "ERR176 - Expected '[' at start of return statement", exprtk_error_location)); return error_node(); @@ -24632,7 +24740,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR174 - Expected ',' between values during call to return", + "ERR177 - Expected ',' between values during call to return", exprtk_error_location)); return error_node(); @@ -24644,7 +24752,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR175 - Zero parameter return statement not allowed", + "ERR178 - Zero parameter return statement not allowed", exprtk_error_location)); return error_node(); @@ -24659,7 +24767,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, prev_token, - "ERR176 - Invalid ']' found during return call", + "ERR179 - Invalid ']' found during return call", exprtk_error_location)); return error_node(); @@ -24712,7 +24820,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR177 - Invalid sequence of variable '"+ symbol + "' and bracket", + "ERR180 - Invalid sequence of variable '"+ symbol + "' and bracket", exprtk_error_location)); return false; @@ -24760,7 +24868,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR178 - Invalid sequence of brackets", + "ERR181 - Invalid sequence of brackets", exprtk_error_location)); return false; @@ -24857,7 +24965,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR179 - Failed to generate node for function: '" + symbol + "'", + "ERR182 - Failed to generate node for function: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -24883,7 +24991,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR180 - Failed to generate node for vararg function: '" + symbol + "'", + "ERR183 - Failed to generate node for vararg function: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -24909,7 +25017,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR181 - Failed to generate node for generic function: '" + symbol + "'", + "ERR184 - Failed to generate node for generic function: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -24936,7 +25044,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR182 - Failed to generate node for string function: '" + symbol + "'", + "ERR185 - Failed to generate node for string function: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -24962,7 +25070,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR183 - Invalid use of reserved symbol '" + symbol + "'", + "ERR186 - Invalid use of reserved symbol '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -25025,7 +25133,7 @@ namespace exprtk set_error( make_error(parser_error::e_symtab, current_token(), - "ERR184 - Failed to create variable: '" + symbol + "'" + + "ERR187 - Failed to create variable: '" + symbol + "'" + (error_message.empty() ? "" : " - " + error_message), exprtk_error_location)); @@ -25045,7 +25153,7 @@ namespace exprtk set_error( make_error(parser_error::e_symtab, current_token(), - "ERR185 - Failed to resolve symbol: '" + symbol + "'" + + "ERR188 - Failed to resolve symbol: '" + symbol + "'" + (error_message.empty() ? "" : " - " + error_message), exprtk_error_location)); } @@ -25057,7 +25165,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR186 - Undefined symbol: '" + symbol + "'", + "ERR189 - Undefined symbol: '" + symbol + "'", exprtk_error_location)); return error_node(); @@ -25164,7 +25272,7 @@ namespace exprtk set_error( make_error(parser_error::e_symtab, current_token(), - "ERR187 - Variable or function detected, yet symbol-table is invalid, Symbol: " + current_token().value, + "ERR190 - Variable or function detected, yet symbol-table is invalid, Symbol: " + current_token().value, exprtk_error_location)); return error_node(); @@ -25188,7 +25296,7 @@ namespace exprtk set_error( make_error(parser_error::e_numeric, current_token(), - "ERR188 - Failed generate node for scalar: '" + current_token().value + "'", + "ERR191 - Failed generate node for scalar: '" + current_token().value + "'", exprtk_error_location)); return error_node(); @@ -25202,7 +25310,7 @@ namespace exprtk set_error( make_error(parser_error::e_numeric, current_token(), - "ERR189 - Failed to convert '" + current_token().value + "' to a number", + "ERR192 - Failed to convert '" + current_token().value + "' to a number", exprtk_error_location)); return error_node(); @@ -25229,7 +25337,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR190 - Expected ')' instead of: '" + current_token().value + "'", + "ERR193 - Expected ')' instead of: '" + current_token().value + "'", exprtk_error_location)); free_node(node_allocator_,branch); @@ -25254,7 +25362,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR191 - Expected ']' instead of: '" + current_token().value + "'", + "ERR194 - Expected ']' instead of: '" + current_token().value + "'", exprtk_error_location)); free_node(node_allocator_,branch); @@ -25279,7 +25387,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR192 - Expected '}' instead of: '" + current_token().value + "'", + "ERR195 - Expected '}' instead of: '" + current_token().value + "'", exprtk_error_location)); free_node(node_allocator_,branch); @@ -25319,7 +25427,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR193 - Premature end of expression[1]", + "ERR196 - Premature end of expression[1]", exprtk_error_location)); return error_node(); @@ -25329,7 +25437,7 @@ namespace exprtk set_error( make_error(parser_error::e_syntax, current_token(), - "ERR194 - Premature end of expression[2]", + "ERR197 - Premature end of expression[2]", exprtk_error_location)); return error_node(); @@ -26022,19 +26130,19 @@ namespace exprtk return false; else return ( - (details::e_lt == operation) || - (details::e_lte == operation) || - (details::e_gt == operation) || - (details::e_gte == operation) || - (details::e_eq == operation) || - (details::e_ne == operation) || - (details::e_equal == operation) || - (details::e_and == operation) || - (details::e_nand == operation) || - (details:: e_or == operation) || - (details:: e_nor == operation) || - (details:: e_xor == operation) || - (details::e_xnor == operation) + (details::e_lt == operation) || + (details::e_lte == operation) || + (details::e_gt == operation) || + (details::e_gte == operation) || + (details::e_eq == operation) || + (details::e_ne == operation) || + (details::e_equal == operation) || + (details::e_and == operation) || + (details::e_nand == operation) || + (details:: e_or == operation) || + (details:: e_nor == operation) || + (details:: e_xor == operation) || + (details::e_xnor == operation) ); } @@ -26228,8 +26336,8 @@ namespace exprtk { if ((0 == condition) || (0 == consequent)) { - free_node(*node_allocator_, condition ); - free_node(*node_allocator_, consequent ); + free_node(*node_allocator_, condition); + free_node(*node_allocator_, consequent); free_node(*node_allocator_, alternative); return error_node(); @@ -26240,7 +26348,7 @@ namespace exprtk // True branch if (details::is_true(condition)) { - free_node(*node_allocator_, condition ); + free_node(*node_allocator_, condition); free_node(*node_allocator_, alternative); return consequent; @@ -26248,7 +26356,7 @@ namespace exprtk // False branch else { - free_node(*node_allocator_, condition ); + free_node(*node_allocator_, condition); free_node(*node_allocator_, consequent); if (alternative) @@ -26260,11 +26368,11 @@ namespace exprtk else if ((0 != consequent) && (0 != alternative)) { return node_allocator_-> - allocate<conditional_node_t>(condition,consequent,alternative); + allocate<conditional_node_t>(condition, consequent, alternative); } else return node_allocator_-> - allocate<cons_conditional_node_t>(condition,consequent); + allocate<cons_conditional_node_t>(condition, consequent); } #ifndef exprtk_disable_string_capabilities @@ -26274,8 +26382,8 @@ namespace exprtk { if ((0 == condition) || (0 == consequent)) { - free_node(*node_allocator_, condition ); - free_node(*node_allocator_, consequent ); + free_node(*node_allocator_, condition); + free_node(*node_allocator_, consequent); free_node(*node_allocator_, alternative); return error_node(); @@ -26286,7 +26394,7 @@ namespace exprtk // True branch if (details::is_true(condition)) { - free_node(*node_allocator_, condition ); + free_node(*node_allocator_, condition); free_node(*node_allocator_, alternative); return consequent; @@ -26294,7 +26402,7 @@ namespace exprtk // False branch else { - free_node(*node_allocator_, condition ); + free_node(*node_allocator_, condition); free_node(*node_allocator_, consequent); if (alternative) @@ -26306,7 +26414,7 @@ namespace exprtk } else if ((0 != consequent) && (0 != alternative)) return node_allocator_-> - allocate<conditional_string_node_t>(condition,consequent,alternative); + allocate<conditional_string_node_t>(condition, consequent, alternative); else return error_node(); } @@ -26333,7 +26441,7 @@ namespace exprtk result = node_allocator_->allocate<details::null_node<Type> >(); free_node(*node_allocator_, condition); - free_node(*node_allocator_, branch ); + free_node(*node_allocator_, branch); return result; } @@ -26370,7 +26478,7 @@ namespace exprtk } free_node(*node_allocator_, condition); - free_node(*node_allocator_, branch ); + free_node(*node_allocator_, branch); return error_node(); } @@ -26407,16 +26515,16 @@ namespace exprtk result = node_allocator_->allocate<details::null_node<Type> >(); free_node(*node_allocator_, initialiser); - free_node(*node_allocator_, condition ); + free_node(*node_allocator_, condition); free_node(*node_allocator_, incrementor); - free_node(*node_allocator_, loop_body ); + free_node(*node_allocator_, loop_body); return result; } else if (details::is_null_node(condition)) { free_node(*node_allocator_, initialiser); - free_node(*node_allocator_, condition ); + free_node(*node_allocator_, condition); free_node(*node_allocator_, incrementor); return loop_body; @@ -28432,12 +28540,12 @@ namespace exprtk { case details::e_div : new_cobnode = expr_gen.node_allocator_-> template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > > - (c / cobnode->c(),cobnode->move_branch(0)); + (c / cobnode->c(), cobnode->move_branch(0)); break; case details::e_mul : new_cobnode = expr_gen.node_allocator_-> template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > > - (c / cobnode->c(),cobnode->move_branch(0)); + (c / cobnode->c(), cobnode->move_branch(0)); break; default : return error_node(); @@ -28486,11 +28594,11 @@ namespace exprtk { const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value(); - details::free_node(*(expr_gen.node_allocator_),branch[1]); + details::free_node(*(expr_gen.node_allocator_), branch[1]); if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation)) { - free_node(*expr_gen.node_allocator_,branch[0]); + free_node(*expr_gen.node_allocator_, branch[0]); return expr_gen(T(0)); } @@ -35656,9 +35764,7 @@ namespace exprtk { scoped_bft<func_1param> sb(*this); base_func::update(v0); - T result = this->value(base_func::expression); - - return result; + return this->value(base_func::expression); } }; @@ -35672,9 +35778,7 @@ namespace exprtk { scoped_bft<func_2param> sb(*this); base_func::update(v0, v1); - T result = this->value(base_func::expression); - - return result; + return this->value(base_func::expression); } }; @@ -35688,9 +35792,7 @@ namespace exprtk { scoped_bft<func_3param> sb(*this); base_func::update(v0, v1, v2); - T result = this->value(base_func::expression); - - return result; + return this->value(base_func::expression); } }; @@ -35704,9 +35806,7 @@ namespace exprtk { scoped_bft<func_4param> sb(*this); base_func::update(v0, v1, v2, v3); - T result = this->value(base_func::expression); - - return result; + return this->value(base_func::expression); } }; @@ -35720,9 +35820,7 @@ namespace exprtk { scoped_bft<func_5param> sb(*this); base_func::update(v0, v1, v2, v3, v4); - T result = this->value(base_func::expression); - - return result; + return this->value(base_func::expression); } }; @@ -35736,9 +35834,7 @@ namespace exprtk { scoped_bft<func_6param> sb(*this); base_func::update(v0, v1, v2, v3, v4, v5); - T result = this->value(base_func::expression); - - return result; + return this->value(base_func::expression); } }; @@ -35785,8 +35881,6 @@ namespace exprtk const Sequence<std::string,Allocator>& var_list, const bool override = false) { - const std::size_t n = var_list.size(); - const typename std::map<std::string,expression_t>::iterator itr = expr_map_.find(name); if (expr_map_.end() != itr) @@ -35804,6 +35898,8 @@ namespace exprtk if (compile_expression(name,expression,var_list)) { + const std::size_t n = var_list.size(); + fp_map_[n][name]->setup(expr_map_[name]); return true; @@ -35869,7 +35965,7 @@ namespace exprtk inline bool add(const function& f, const bool override = false) { - return add(f.name_,f.expression_,f.v_,override); + return add(f.name_, f.expression_, f.v_,override); } private: @@ -36493,8 +36589,8 @@ namespace exprtk return false; \ } \ - exprtk_register_function("print" , p) - exprtk_register_function("println" ,pl) + exprtk_register_function("print" , p) + exprtk_register_function("println", pl) #undef exprtk_register_function return true; @@ -38160,9 +38256,9 @@ namespace exprtk namespace information { static const char* library = "Mathematical Expression Toolkit"; - static const char* version = "2.7182818284590452353602874713526624977572470936" - "999595749669676277240766303535475945713821785251"; - static const char* date = "20170505"; + static const char* version = "2.71828182845904523536028747135266249775724709369" + "9959574966967627724076630353547594571382178525166"; + static const char* date = "20180101"; static inline std::string data() { diff --git a/src/core/mpi/BufferDataTypeExtensions.h b/src/core/mpi/BufferDataTypeExtensions.h index b05128c4a193aebd46f9f31fec2ed89dc41c30ec..bf51bd9f83ad3390976f72fea1502799c337317c 100644 --- a/src/core/mpi/BufferDataTypeExtensions.h +++ b/src/core/mpi/BufferDataTypeExtensions.h @@ -33,6 +33,7 @@ #include <boost/integer.hpp> #include <boost/uuid/uuid.hpp> +#include <array> #include <deque> #include <limits> #include <list> @@ -82,6 +83,51 @@ struct BufferSizeTrait< std::pair<T1,T2> > { // ----------------------------- Standard Container Support ----------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------------- +template< typename T, // Element type of SendBuffer + typename G, // Growth policy of SendBuffer + typename Cont > // Container +void sendNonResizableContainer( GenericSendBuffer<T,G> & buf, const Cont & container ) +{ + buf.addDebugMarker( "ar" ); + for( const auto & it : container ) + buf << it; +} + +template< typename T, // Element type of RecvBuffer + typename Cont > // Container +void recvNonResizableContainer( GenericRecvBuffer<T> & buf, Cont & container ) +{ + buf.readDebugMarker( "ar" ); + for( auto & it : container ) + buf >> it; +} + +template< typename T, // Element type of SendBuffer + typename G, // Growth policy of SendBuffer + typename CT, // Element type + std::size_t N > // Array size +GenericSendBuffer<T,G>& operator<<( GenericSendBuffer<T,G> & buf, const std::array<CT, N> & array ) +{ + sendNonResizableContainer(buf, array); + return buf; +} + +template< typename T, // Element type of RecvBuffer + typename CT, // Element type + std::size_t N > // Array size +GenericRecvBuffer<T>& operator>>( GenericRecvBuffer<T> & buf, std::array<CT, N> & array ) +{ + recvNonResizableContainer(buf, array); + return buf; +} + +template<typename T, std::size_t N> +struct BufferSizeTrait< std::array< T, N > > { + static const bool constantSize = true; + static const uint_t size = N * sizeof(T) + BUFFER_DEBUG_OVERHEAD; +}; + + template< typename T, // Element type of SendBuffer typename G, // Growth policy of SendBuffer typename Cont> // Container diff --git a/src/core/ptrvector/Algorithm.h b/src/core/ptrvector/Algorithm.h deleted file mode 100644 index c00063d702e55c804b1b02ceadf44845a1ff1069..0000000000000000000000000000000000000000 --- a/src/core/ptrvector/Algorithm.h +++ /dev/null @@ -1,95 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file Algorithm.h -//! \ingroup core -//! \author Klaus Iglberger -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -// -//====================================================================================================================== - -#pragma once - - -//************************************************************************************************* -// Includes -//************************************************************************************************* - -#include <boost/type_traits/is_base_of.hpp> - -namespace walberla { - -//================================================================================================= -// -// POLYMORPHIC COUNT -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Counts the pointer to objects with dynamic type \a D. - * - * \param first Iterator to the first pointer of the pointer range. - * \param last Iterator to the pointer one past the last pointer of the pointer range. - * \return The number of objects with dynamic type \a D. - * - * This function traverses the range \f$ [first,last) \f$ of pointers to objects with static - * type \a S and counts all polymorphic pointers to objects of dynamic type \a D. Note that - * in case \a D is not a type derived from \a S, a compile time error is created! - */ -template< typename D // Dynamic type of the objects - , typename S > // Static type of the objects -inline size_t polymorphicCount( S *const * first, S *const * last ) -{ - static_assert(boost::is_base_of<S, D>::value && !boost::is_base_of<D, S>::value, "D has to be strictly derived from S"); - - size_t count( 0 ); - for( S *const * it=first; it!=last; ++it ) - if( dynamic_cast<D*>( *it ) ) ++count; - return count; -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// POLYMORPHIC FIND -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Finds the next pointer to an object with dynamic type \a D. - * - * \param first Iterator to the first pointer of the pointer range. - * \param last Iterator to the pointer one past the last pointer of the pointer range. - * \return The next pointer to an object with dynamic type \a D. - * - * This function traverses the range \f$ [first,last) \f$ of pointers to objects with static - * type \a S until it finds the next polymorphic pointer to an object of dynamic type \a D. - * Note that in case \a D is not a type derived from \a S, a compile time error is created! - */ -template< typename D // Dynamic type of the objects - , typename S > // Static type of the objects -inline S *const * polymorphicFind( S *const * first, S *const * last ) -{ - static_assert(boost::is_base_of<S, D>::value && !boost::is_base_of<D, S>::value, "D has to be strictly derived from S"); - - while( first != last && !dynamic_cast<D*>( *first ) ) ++first; - return first; -} -//************************************************************************************************* - -} // namespace diff --git a/src/core/ptrvector/Null.h b/src/core/ptrvector/Null.h deleted file mode 100644 index 0f08813a0244eacfe1f82e9f9249308e924c932c..0000000000000000000000000000000000000000 --- a/src/core/ptrvector/Null.h +++ /dev/null @@ -1,289 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file Null.h -//! \ingroup core -//! \author Klaus Iglberger -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -// -//====================================================================================================================== - -#pragma once - -namespace walberla { - -//================================================================================================= -// -// CLASS DEFINITION -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Safe C++ NULL pointer implementation. - * \ingroup util - * - * This implementation offers a remedy for the use of the NULL pointer in C++. For this, the - * NULL macro is replaced by an instance of the Null class, which can only be assigned and - * compared with pointers and pointers-to-member. Therefore the use of NULL regains the type - * safety it lost in C++ due to the strict C++ type system.\n - * The NULL pointer is used exactly as before: - - \code - int* pi = NULL; - if( pi == NULL ) {...} - \endcode - */ -class Null -{ -public: - //**Constructor********************************************************************************* - /*!\name Constructor */ - //@{ - inline Null(); - //@} - //********************************************************************************************** - - //**Destructor********************************************************************************** - // No explicitly declared destructor. - //********************************************************************************************** - - //**Conversion operators************************************************************************ - /*!\name Conversion operators */ - //@{ - template< typename T > - inline operator T*() const; - - template< typename T, typename C > - inline operator T C::*() const; - //@} - //********************************************************************************************** - - //**Utility functions*************************************************************************** - /*!\name Utility functions */ - //@{ - template< typename T > - inline bool equal( const T* rhs ) const; - - template< typename T, typename C > - inline bool equal( const T C::* rhs ) const; - //@} - //********************************************************************************************** - -private: - //**Forbidden operations************************************************************************ - /*!\name Forbidden operations */ - //@{ - Null( const Null& n ); //!< Copy constructor (private & undefined) - Null& operator=( const Null& n ); //!< Copy assignment operator (private & undefined) - void* operator&() const; //!< Address operator (private & undefined) - //@} - //********************************************************************************************** -}; -//************************************************************************************************* - - - - -//================================================================================================= -// -// CONSTRUCTOR -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief The default constructor of the Null class. - */ -inline Null::Null() -{} -//************************************************************************************************* - - - - -//================================================================================================= -// -// CONVERSION OPERATORS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Conversion operator to a pointer. - * - * This conversion operator offers a type safe conversion of zero to a pointer of any kind. - */ -template< typename T > -inline Null::operator T*() const -{ - return 0; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Conversion operator to a pointer-to-member. - * - * This conversion operator offers the type safe conversion of zero to a pointer-to-member of - * any kind. - */ -template< typename T, typename C > -inline Null::operator T C::*() const -{ - return 0; -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// UTILITY FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Comparison between Null and a pointer. - * - * The function offers a type safe comparison between zero and an arbitrary pointer. - */ -template< typename T > -inline bool Null::equal( const T* rhs ) const -{ - return rhs == 0; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Comparison between Null and a pointer-to-member. - * - * The function offers a type safe comparison between zero and an arbitrary pointer-to-member. - */ -template< typename T, typename C > -inline bool Null::equal( const T C::* rhs ) const -{ - return rhs == 0; -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// GLOBAL OPERATORS -// -//================================================================================================= - -//************************************************************************************************* -/*!\name Null operators */ -//@{ -template< typename T > -inline bool operator==( const Null& lhs, const T& rhs ); - -template< typename T > -inline bool operator==( const T& lhs, const Null& rhs ); - -template< typename T > -inline bool operator!=( const Null& lhs, const T& rhs ); - -template< typename T > -inline bool operator!=( const T& lhs, const Null& rhs ); -//@} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Equality comparison between Null and a pointer or pointer-to-member. - * - * This operator takes a reference to an object of type T instead of a pointer of a pointer- - * to-member to avoid the ambiguity with the built-in pointer comparison operators. However, - * only pointers and pointers-to-member can be compared to Null. - */ -template< typename T > -inline bool operator==( const Null& lhs, const T& rhs ) -{ - return lhs.equal( rhs ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Equality comparison between a pointer or pointer-to-member and Null. - * - * This operator takes a reference to an object of type T instead of a pointer of a pointer- - * to-member to avoid the ambiguity with the built-in pointer comparison operators. However, - * only pointers and pointers-to-member can be compared to Null. - */ -template< typename T > -inline bool operator==( const T& lhs, const Null& rhs ) -{ - return rhs.equal( lhs ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Inequality comparison between Null and a pointer or pointer-to-member. - * - * This operator takes a reference to an object of type T instead of a pointer of a pointer- - * to-member to avoid the ambiguity with the built-in pointer comparison operators. However, - * only pointers and pointers-to-member can be compared to Null. - */ -template< typename T > -inline bool operator!=( const Null& lhs, const T& rhs ) -{ - return !lhs.equal( rhs ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Inequality comparison between a pointer or pointer-to-member and Null. - * - * This operator takes a reference to an object of type T instead of a pointer of a pointer- - * to-member to avoid the ambiguity with the built-in pointer comparison operators. However, - * only pointers and pointers-to-member can be compared to Null. - */ -template< typename T > -inline bool operator!=( const T& lhs, const Null& rhs ) -{ - return !rhs.equal( lhs ); -} -//************************************************************************************************* - -} // namespace - - - - -////================================================================================================= -//// -//// NULL DEFINITION -//// -////================================================================================================= - -//#ifdef NULL -//# undef NULL -//#endif - -////************************************************************************************************* -///*!\brief Global NULL pointer. -// * \ingroup util -// * -// * This instance of the Null class replaces the NULL macro to ensure a type-safe NULL pointer. -// */ -//const walberla::Null NULL; -////************************************************************************************************* diff --git a/src/core/ptrvector/PtrIterator.h b/src/core/ptrvector/PtrIterator.h deleted file mode 100644 index a6ecef7f3b6194ead74e78f2b52e030dd3c9b704..0000000000000000000000000000000000000000 --- a/src/core/ptrvector/PtrIterator.h +++ /dev/null @@ -1,548 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file PtrIterator.h -//! \ingroup core -//! \author Klaus Iglberger -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -// -//====================================================================================================================== - -#pragma once - - -//************************************************************************************************* -// Includes -//************************************************************************************************* - -#include <iterator> -#include <core/ptrvector/Null.h> - -namespace walberla { - -//================================================================================================= -// -// CLASS DEFINITION -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Implementation of an iterator for pointer vectors. - * \ingroup util - * - * The PtrIterator class follows the example of the random-access iterator classes of the STL. - * However, the focus of this iterator implementation is the use with (polymorphic) pointers. - * Since the physics engine makes heavy use of polymorphic pointers, this implementation eases - * the use of iterators over a range of pointers and improves the semantics on these pointers.\n - * - * In contrast to the STL iterators, the PtrIterator class slightly changes the meaning of the - * access operators. Consider the following example: - - \code - // Definition of class A - class A - { - public: - A( int i=0 ):i_(i) {} - - void set( int i ) { i_ = i; } - int get() const { return i_; } - - private: - int i_; - }; - - // Definition of a pointer vector for class A - typedef PtrVector<A> AVector; - - AVector vector; - AVector::Iterator it = vector.begin(); - - // The subscript operator returns a handle to the underlying object - A* a1 = it[0]; - - // The dereference operator returns a handle to the underlying object - A* a2 = *it; - - // The member access operator offers direct access to the underlying object - it->set( 2 ); - \endcode - - * The constant iterators (iterator over constant objects) prohibit the access to non-const - * member functions. Therefore the following operation results in a compile-time error: - - \code - AVector vector; - AVector::ConstIterator it = vector.begin(); - - it->set( 2 ); // Compile-time error! - \endcode - */ -template< typename Type > -class PtrIterator -{ -public: - //**Type definitions**************************************************************************** - // pe naming convention - typedef std::random_access_iterator_tag IteratorCategory; //!< The iterator category. - typedef Type* ValueType; //!< Type of the underlying pointers. - typedef Type* const PointerType; //!< Pointer return type. - typedef ValueType const& ReferenceType; //!< Reference return type. - typedef ValueType const* IteratorType; //!< Type of the internal pointer. - typedef std::ptrdiff_t DifferenceType; //!< Difference between two iterators. - - // STL iterator requirements - typedef IteratorCategory iterator_category; //!< The iterator category. - typedef ValueType value_type; //!< Type of the underlying pointers. - typedef PointerType pointer; //!< Pointer return type. - typedef ReferenceType reference; //!< Reference return type. - typedef DifferenceType difference_type; //!< Difference between two iterators. - //********************************************************************************************** - - //**Constructors******************************************************************************** - /*!\name Constructors */ - //@{ - inline PtrIterator(); - explicit inline PtrIterator( const IteratorType& it ); - - template< typename Other > - inline PtrIterator( const PtrIterator<Other>& it ); - - // No explicitly declared copy constructor. - //@} - //********************************************************************************************** - - //**Destructor********************************************************************************** - // No explicitly declared destructor. - //********************************************************************************************** - - //**Copy assignment operator******************************************************************** - // No explicitly declared copy assignment operator. - //********************************************************************************************** - - //**Operators*********************************************************************************** - /*!\name Operators */ - //@{ - inline PtrIterator& operator++(); - inline PtrIterator operator++( int ); - inline PtrIterator& operator--(); - inline PtrIterator operator--( int ); - inline PtrIterator& operator+=( DifferenceType n ); - inline PtrIterator operator+ ( DifferenceType n ) const; - inline PtrIterator& operator-=( DifferenceType n ); - inline PtrIterator operator- ( DifferenceType n ) const; - inline DifferenceType operator- ( const PtrIterator& it ) const; - //@} - //********************************************************************************************** - - //**Access operators**************************************************************************** - /*!\name Access operators */ - //@{ - inline PointerType& operator[]( DifferenceType n ) const; - inline PointerType& operator*() const; - inline PointerType& operator->() const; - //@} - //********************************************************************************************** - - //**Utility functions*************************************************************************** - /*!\name Utility functions */ - //@{ - inline const IteratorType& base() const; - //@} - //********************************************************************************************** - -private: - //**Member variables**************************************************************************** - /*!\name Member variables */ - //@{ - IteratorType it_; //!< Pointer to the current memory location. - //@} - //********************************************************************************************** -}; -//************************************************************************************************* - - - - -//================================================================================================= -// -// CONSTRUCTORS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Default constructor for PtrIterator. - */ -template< typename Type > -inline PtrIterator<Type>::PtrIterator() - : it_(NULL) // Pointer to the current memory location -{} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Standard constructor for PtrIterator. - * - * \param it The value of the iterator. - */ -template< typename Type > -inline PtrIterator<Type>::PtrIterator( const IteratorType& it ) - : it_(it) // Pointer to the current memory location -{} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Conversion constructor from different PtrIterator instances. - * - * \param it The foreign PtrIterator instance to be copied. - */ -template< typename Type > -template< typename Other > -inline PtrIterator<Type>::PtrIterator( const PtrIterator<Other>& it ) - : it_( it.base() ) // Pointer to the current memory location -{} -//************************************************************************************************* - - - - -//================================================================================================= -// -// OPERATORS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Pre-increment operator. - * - * \return Reference to the incremented pointer iterator. - */ -template< typename Type > -inline PtrIterator<Type>& PtrIterator<Type>::operator++() -{ - ++it_; - return *this; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Post-increment operator. - * - * \return The incremented pointer iterator. - */ -template< typename Type > -inline PtrIterator<Type> PtrIterator<Type>::operator++( int ) -{ - PtrIterator tmp( *this ); - ++it_; - return tmp; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Pre-decrement operator. - * - * \return Reference to the decremented pointer iterator. - */ -template< typename Type > -inline PtrIterator<Type>& PtrIterator<Type>::operator--() -{ - --it_; - return *this; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Post-decrement operator. - * - * \return The decremented pointer iterator. - */ -template< typename Type > -inline PtrIterator<Type> PtrIterator<Type>::operator--( int ) -{ - PtrIterator tmp( *this ); - --it_; - return tmp; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Shifting the iterator by \a n elements to the higher elements. - * - * \param n The number of elements. - * \return Reference to the shifted pointer iterator. - */ -template< typename Type > -inline PtrIterator<Type>& PtrIterator<Type>::operator+=( DifferenceType n ) -{ - it_ += n; - return *this; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Shifting the iterator by \a n elements to the higher elements. - * - * \param n The number of elements. - * \return The shifted pointer iterator. - */ -template< typename Type > -inline PtrIterator<Type> PtrIterator<Type>::operator+( DifferenceType n ) const -{ - return PtrIterator( it_ + n ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Shifting the iterator by \a n elements to the lower elements. - * - * \param n The number of elements. - * \return Reference to the shifted pointer iterator. - */ -template< typename Type > -inline PtrIterator<Type>& PtrIterator<Type>::operator-=( DifferenceType n ) -{ - it_ -= n; - return *this; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Shifting the iterator by \a n elements to the lower elements. - * - * \param n The number of elements. - * \return The shifted pointer iterator. - */ -template< typename Type > -inline PtrIterator<Type> PtrIterator<Type>::operator-( DifferenceType n ) const -{ - return PtrIterator( it_ - n ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Calculating the number of elements between two pointer iterators. - * - * \param it The right hand side iterator. - * \return The number of elements between the two pointer iterators. - */ -template< typename Type > -inline typename PtrIterator<Type>::DifferenceType PtrIterator<Type>::operator-( const PtrIterator& it ) const -{ - return it_ - it.it_; -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// ACCESS OPERATORS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Subscript operator for the direct element access. - * - * \param index Access index. Accesses the element \a index elements away from the current iterator position. - * \return Handle to the accessed element. - */ -template< typename Type > -inline typename PtrIterator<Type>::PointerType& PtrIterator<Type>::operator[]( DifferenceType index ) const -{ - return it_[index]; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns a handle to the element at the current iterator position. - * - * \return Handle to the element at the current iterator position. - */ -template< typename Type > -inline typename PtrIterator<Type>::PointerType& PtrIterator<Type>::operator*() const -{ - return *it_; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Direct access to the element at the current iterator position. - * - * \return Reference to the element at the current iterator position. - */ -template< typename Type > -inline typename PtrIterator<Type>::PointerType& PtrIterator<Type>::operator->() const -{ - return *it_; -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// UTILITY FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Access to the underlying member of the pointer iterator. - * - * \return Pointer to the current memory location. - */ -template< typename Type > -inline const typename PtrIterator<Type>::IteratorType& PtrIterator<Type>::base() const -{ - return it_; -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// GLOBAL OPERATORS -// -//================================================================================================= - -//************************************************************************************************* -/*!\name PtrIterator operators */ -//@{ -template< typename TypeL, typename TypeR > -inline bool operator==( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs ); - -template< typename TypeL, typename TypeR > -inline bool operator!=( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs ); - -template< typename TypeL, typename TypeR > -inline bool operator<( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs ); - -template< typename TypeL, typename TypeR > -inline bool operator>( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs ); - -template< typename TypeL, typename TypeR > -inline bool operator<=( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs ); - -template< typename TypeL, typename TypeR > -inline bool operator>=( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs ); -//@} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Equality comparison between two PtrIterator objects. - * - * \param lhs The left-hand side pointer iterator. - * \param rhs The right-hand side pointer iterator. - * \return \a true if the iterators point to the same element, \a false if not. - */ -template< typename TypeL, typename TypeR > -inline bool operator==( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs ) -{ - return lhs.base() == rhs.base(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Inequality comparison between two PtrIterator objects. - * - * \param lhs The left-hand side pointer iterator. - * \param rhs The right-hand side pointer iterator. - * \return \a true if the iterators don't point to the same element, \a false if they do. - */ -template< typename TypeL, typename TypeR > -inline bool operator!=( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs ) -{ - return lhs.base() != rhs.base(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Less-than comparison between two PtrIterator objects. - * - * \param lhs The left-hand side pointer iterator. - * \param rhs The right-hand side pointer iterator. - * \return \a true if the left-hand side iterator points to a lower element, \a false if not. - */ -template< typename TypeL, typename TypeR > -inline bool operator<( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs ) -{ - return lhs.base() < rhs.base(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Greater-than comparison between two PtrIterator objects. - * - * \param lhs The left-hand side pointer iterator. - * \param rhs The right-hand side pointer iterator. - * \return \a true if the left-hand side iterator points to a higher element, \a false if not. - */ -template< typename TypeL, typename TypeR > -inline bool operator>( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs ) -{ - return lhs.base() > rhs.base(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Less-or-equal-than comparison between two PtrIterator objects. - * - * \param lhs The left-hand side pointer iterator. - * \param rhs The right-hand side pointer iterator. - * \return \a true if the left-hand side iterator points to a lower or the same element, \a false if not. - */ -template< typename TypeL, typename TypeR > -inline bool operator<=( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs ) -{ - return lhs.base() <= rhs.base(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Greater-or-equal-than comparison between two PtrIterator objects. - * - * \param lhs The left-hand side pointer iterator. - * \param rhs The right-hand side pointer iterator. - * \return \a true if the left-hand side iterator points to a higher or the same element, \a false if not. - */ -template< typename TypeL, typename TypeR > -inline bool operator>=( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs ) -{ - return lhs.base() >= rhs.base(); -} -//************************************************************************************************* - -} // namespace diff --git a/src/core/ptrvector/PtrVector.h b/src/core/ptrvector/PtrVector.h deleted file mode 100644 index 2e62290407295ed080e6b619f7242e709ee952fe..0000000000000000000000000000000000000000 --- a/src/core/ptrvector/PtrVector.h +++ /dev/null @@ -1,2604 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file PtrVector.h -//! \ingroup core -//! \author Klaus Iglberger -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -// -//====================================================================================================================== - -#pragma once - - -//************************************************************************************************* -// Includes -//************************************************************************************************* - -#include <algorithm> -#include <stdexcept> -#include <core/debug/Debug.h> -#include <core/ptrvector/Algorithm.h> -#include <core/ptrvector/Null.h> -#include <core/ptrvector/policies/PtrDelete.h> -#include <core/ptrvector/policies/OptimalGrowth.h> -#include <core/ptrvector/PtrIterator.h> -#include <core/Template.h> - -#include <boost/type_traits/is_base_of.hpp> -#include <boost/type_traits/is_convertible.hpp> - -namespace walberla { - -//================================================================================================= -// -// CLASS DEFINITION -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Implementation of a vector for (polymorphic) pointers. - * \ingroup util - * - * \section basics Basic usage - * - * The \a std::vector is one of the standard libraries most useful tools. It is the standard - * solution for a dynamically allocated, automatically growing, and memory managed array. It - * provides fast random access to its elements, since a vector guarantees that the elements - * lie adjacent in memory and manages the dynamically allocated memory according to the RAII - * idiom.\n - * Yet there are some situations, where users of \a std::vector experience several drawbacks, - * especially when \a std::vector is used in combination with pointers. For instance, a - * \a const_iterator over a range of pointers will not allow the stored pointers to change, - * but the objects behind the pointers remain changeable. The following example illustrates - * that it is possible to change the values of \a double values through an iterator-to-const: - - \code - typedef std::vector<double*> Doubles; - - Doubles doubles; // Creating a vector for pointers to double values - - // Filling the vector with pointers to double values. All values are initialized with 1. - for( size_t i=0; i<10; ++i ) - doubles.push_back( new double( 1.0 ) ); - - // Accessing the first rigid body - Doubles::const_iterator first = doubles.begin(); - **first = 2.0; // Changes the double value through an iterator-to-const - \endcode - - * The basic reason for this behavior is that \a std::vector is unaware of the fact that it - * stores pointers instead of objects and therefore the pointer are considered constant, not - * the objects behind the pointer.\n - * Another drawback of \a std::vector is the fact that during destruction of a vector object - * the dynamically allocated bodies are not deleted. Again, \a std::vector is unaware of the - * special property of pointers and therefore does not apply any kind of deletion policy. It - * basically calls the default destructor for pointers, which in turn does nothing and - * especially does not destroy the attached objects.\n - * A different approach is taken by the Boost \a ptr_vector. A \a ptr_vector is perfectly - * aware of the fact that is stores pointers to dynamically objects (and in consequence may - * only be used with pointers to dynamically allocated objects) and takes full responsibility - * for these resources. However, in order to accomplish this task, \a ptr_vector completely - * abstracts from the fact that it stores pointers and provides a view as if it would contain - * objects instead of pointers. However, unfortunately this strict memory management creates - * problems in the context of \b walberla, where vectors to pointers are used both internally - * (including proper resource management) and outside by the user (without any resource - * management).\n - * \b walberla provides a special vector container for pointers, which is - * a cross of the functionalities of the \a std::vector and \a ptr_vector. The \b walberla PtrVector - * is not a RAII class in the classical sense (as for instance the Boost \a ptr_vector) since - * it does not strictly encapsule the resource management. As in the case of \a std::vector, - * it still is the responsibility of a user of PtrVector to manage the resources accordingly. - * However, it perfectly fits the requirements of \b walberla: PtrVector can be used internally - * to store pointers to dynamically allocated objects and resources within RAII classes, and - * outside of \b walberla by a user as storage for handles to resources that are managed elsewhere. - * In contrast to the \a boost::ptr_vector, the PtrVector provides full access to the contained - * pointers, but its iterators work similar to the \a ptr_vector - * iterator and only provide access to the objects behind the pointers, creating the illusion - * that objects are stored instead of pointers: - - \code - typedef walberla::PtrVector<double> Doubles; - Doubles doubles; // Creating an empty PtrVector for pointers to double values - - doubles.pushBack( new double(1.0) ); // A new pointer-to-double is added to the vector - - double_vector::iterator first = doubles.begin(); - *first = 2.0; // No indirection needed - - Doubles::ConstIterator second( first+1 ); - *second = 3.0; // Compile time error! It is not possible to change double - // values via an iterator-to-const - \endcode - - * Notice the differences in the usage of the iterator in contrast to the \a std::vector and - * \a boost::ptr_vector. In contrast to them the functions of PtrVector follow the naming - * convention of the \b walberla physics engine (i.e. pushBack instead of push_back). In addition, - * the underlying iterator adds an additional dereference to all access operators, which eases - * the access to the underlying objects: - - \code - // STL style: - **first = 2.0; - - // walberla style: - *first = 2.0; - \endcode - - * A noteworthy difference between the STL vector and the pointer vector is the used template - * argument: instead of the pointer type, the \b walberla pointer vector is only provided with the - * type of the underlying objects: - - \code - // STL style: - std::vector<double*> vector; - - // walberla style: - walberla::PtrVector<double> vector; - \endcode - - * Additionally, the \b walberla pointer vector offers some limited possibilities to configure the - * memory management and the growth of the internal storage, and implements special features - * for polymorphic pointers, as for instance a convenient way to iterate over a subset of - * polymorphic objects contained in the pointer vector.\n\n - * - * - * \section polymorphic Polymorphic pointers - * - * For polymorphic pointers, the PtrVector class additionally offers two special iterators to - * iterate over all objects of a specific type: the CastIterator and ConstCastIterator. - - \code - // Definition of class A and the derived type B - class A { ... }; - class B : public A { ... }; - - // Definition of function f for non-const pointer vectors - void f( PtrVector<A>& vector ) - { - PtrVector<A>::CastIterator<B> begin = vector.begin<B>(); - PtrVector<A>::CastIterator<B> end = vector.end<B>(); - - // Loop over all objects of type B contained in the vector - for( ; begin!=end; ++begin ) - ... - } - - // Definition of function f for const pointer vectors - void f( const PtrVector<A>& vector ) - { - PtrVector<A>::ConstCastIterator<B> begin = vector.begin<B>(); - PtrVector<A>::ConstCastIterator<B> end = vector.end<B>(); - - // Loop over all objects of type B contained in the vector - for( ; begin!=end; ++begin ) - } - \endcode - - * In the example, the cast iterators are used to iterate over all objects of type \a B within - * the pointer vector, where \a B must be a type derived from \a A. The attempt to use these - * iterators for types that are not derived from \a A results in a compile time error. Note that - * the usage of the cast iterators is computationally more expensive than the use of the standard - * iterators. Therefore these iterators should not be used unless a down-cast is really necessary, - * e.g. in order to access a type specific function.\n\n - * - * - * \section container Using a pointer vector within other container classes - * - * If a pointer vector is used within an other container and is used to store polymorphic pointers, - * you might face the problem of not being able to create type definitions for the cast iterators. - * Whereas it is possible to create typedefs for the standard iterators, it is unfortunately not - * possible (yet) to create type definitions for template classes. In order to create a new return - * type within the container, the following approach could be taken: - - \code - template< typename A > - class Container - { - public: - template< typename C > - struct CastIterator : public PtrVector<A>::CastIterator<C> - { - CastIterator( const PtrVector<A>::CastIterator<C>& it ) - : PtrVector<A>::CastIterator<C>( it ) // Initializing the base class - {} - }; - - template< typename C > - CastIterator<C> begin(); - - template< typename C > - CastIterator<C> end(); - - private: - PtrVector<A> vector_; - }; - \endcode - - * Instead of a typedef within the Container class, a new class CastIterator is derived from the - * PtrVector::CastIterator class. This approach acts similar as the typedef as a user can now - * use the Container as follows: - - \code - class A { ... }; - class B : public A { ... }; - - Container<A>::CastIterator<B> begin; - \endcode - - * This provides the same abstraction from the internal implementation as the desired typedef. The - * same approach could be taken for a ConstCastIterator definition. However, to keep the code - * footprint small you should consider using the original type instead.\n\n - * - * - * \section adaptions Adapting a pointer vector - * - * The growth and deletion behavior of the PtrVector class can be adapted to any specific task. The - * second template argument of the PtrVector specifies the growth rate. The following growth rates - * can be selected: - * - * - ConstantGrowth - * - LinearGrowth - * - OptimalGrowth (the default behavior) - * - * The third template argument of the PtrVector specifies the deletion behavior for the case that - * the pointer vector is destroyed. Note that the deletion behavior has only limited effect on - * the memory management of the contained resources. For instance, copying a PtrVector always - * results in a shallow copy, i.e., the contained resources are not copied/cloned. Therefore the - * deletion policy should be considered a convenience functionality in the context of a resource - * managing class. The following policies can be selected: - * - * - NoDelete : No deletion of the contained pointers (the default behavior). - * - PtrDelete : Applies \a delete to all contained pointers. - * - ArrayDelete : Applies \a delete[] to all contained pointers.\n\n - */ -template< typename T // Type - , typename D = PtrDelete // Deletion policy - , typename G = OptimalGrowth > // Growth policy -class PtrVector -{ -private: - //**Friend declarations************************************************************************* - /*! \cond internal */ - template< typename T2, typename D2, typename G2 > friend class PtrVector; - /*! \endcond */ - //********************************************************************************************** - -public: - //**Type definitions**************************************************************************** - typedef T* ValueType; //!< Type of the underlying values. - typedef T* PointerType; //!< Pointer to a non-const object. - typedef const T* ConstPointerType; //!< Pointer to a const object. - typedef T*& ReferenceType; //!< Reference to a non-const object. - typedef T*const& ConstReferenceType; //!< Reference to a const object. - typedef size_t SizeType; //!< Size type of the pointer vector. - typedef PtrIterator<T> Iterator; //!< Iterator over non-const objects. - typedef PtrIterator<const T> ConstIterator; //!< Iterator over const objects. - typedef D DeletionPolicy; //!< Type of the deletion policy. - typedef G GrowthPolicy; //!< Type of the growth policy. - - // STL iterator requirements - typedef ValueType value_type; //!< Type of the underlying values. - typedef PointerType pointer; //!< Pointer to a non-const object. - typedef ConstPointerType const_pointer; //!< Pointer to a const object. - typedef ReferenceType reference; //!< Reference to a non-const object. - typedef ConstReferenceType const_reference; //!< Reference to a const object. - typedef SizeType size_type; //!< Size type of the pointer vector. - //********************************************************************************************** - - //**Forward declarations for nested classes***************************************************** - template< typename C > class CastIterator; - template< typename C > class ConstCastIterator; - //********************************************************************************************** - - //**Constructors******************************************************************************** - /*!\name Constructors */ - //@{ - explicit inline PtrVector( SizeType initCapacity = 0 ); - inline PtrVector( const PtrVector& pv ); - - template< typename T2, typename D2, typename G2 > - inline PtrVector( const PtrVector<T2,D2,G2>& pv ); - //@} - //********************************************************************************************** - - //**Destructor********************************************************************************** - /*!\name Destructor */ - //@{ - inline ~PtrVector(); - //@} - //********************************************************************************************** - - //**Assignment operators************************************************************************ - /*!\name Assignment operators */ - //@{ - PtrVector& operator=( const PtrVector& pv ); - - template< typename T2, typename D2, typename G2 > - PtrVector& operator=( const PtrVector<T2,D2,G2>& pv ); - //@} - //********************************************************************************************** - - //**Get functions******************************************************************************* - /*!\name Get functions */ - //@{ - inline SizeType maxSize() const; - inline SizeType size() const; - template< typename C > inline SizeType size() const; - inline SizeType capacity() const; - inline bool isEmpty() const; - //@} - //********************************************************************************************** - - //**Access functions**************************************************************************** - /*!\name Access functions */ - //@{ - inline ReferenceType operator[]( SizeType index ); - inline ConstReferenceType operator[]( SizeType index ) const; - inline ReferenceType front(); - inline ConstReferenceType front() const; - inline ReferenceType back(); - inline ConstReferenceType back() const; - //@} - //********************************************************************************************** - - //**Iterator functions************************************************************************** - /*!\name Iterator functions */ - //@{ - inline Iterator begin(); - inline ConstIterator begin() const; - template< typename C > inline CastIterator<C> begin(); - template< typename C > inline ConstCastIterator<C> begin() const; - - inline Iterator end(); - inline ConstIterator end() const; - template< typename C > inline CastIterator<C> end(); - template< typename C > inline ConstCastIterator<C> end() const; - //@} - //********************************************************************************************** - - //**Element functions*************************************************************************** - /*!\name Element functions */ - //@{ - inline void pushBack ( PointerType p ); - inline void popBack (); - inline void releaseBack(); - - template< typename IteratorType > - inline void assign( IteratorType first, IteratorType last ); - - inline Iterator insert( Iterator pos, PointerType p ); - - template< typename IteratorType > - inline void insert( Iterator pos, IteratorType first, IteratorType last ); - - /*! \cond internal */ - template< typename IteratorType > - inline void insert( Iterator pos, IteratorType* first, IteratorType* last ); - /*! \endcond */ - - inline Iterator erase ( Iterator pos ); - template< typename C > inline CastIterator<C> erase ( CastIterator<C> pos ); - inline Iterator release( Iterator pos ); - template< typename C > inline CastIterator<C> release( CastIterator<C> pos ); - inline void clear (); - //@} - //********************************************************************************************** - - //**Utility functions*************************************************************************** - /*!\name Utility functions */ - //@{ - void reserve( SizeType newCapacity ); - inline void swap( PtrVector& pv ) /* throw() */; - //@} - //********************************************************************************************** - -private: - //**Helper functions**************************************************************************** - /*!\name Helper functions */ - //@{ - inline size_t calcCapacity ( size_t minCapacity ) const; - inline void deleteElement( PointerType ptr ) const; - //@} - //********************************************************************************************** - - //**Insertion helper functions****************************************************************** - /*!\name Insertion helper functions */ - //@{ - void insert( T**const pos, PointerType p ); - - /*! \cond internal */ - template< typename IteratorType > - inline void insert( Iterator pos, IteratorType first, IteratorType last, std::input_iterator_tag ); - - template< typename IteratorType > - inline void insert( Iterator pos, IteratorType first, IteratorType last, std::random_access_iterator_tag ); - /*! \endcond */ - - template< typename IteratorType > - void insert( T** pos, IteratorType first, IteratorType last, SizeType n ); - //@} - //********************************************************************************************** - - //**Member variables**************************************************************************** - /*!\name Member variables */ - //@{ - SizeType size_; //!< The current size of the pointer vector. - SizeType capacity_; //!< The capacity of the pointer vector. - PointerType* begin_; //!< Pointer to the first element of the pointer vector. - PointerType* end_; //!< Pointer to the last element of the pointer vector. - //@} - //********************************************************************************************** - -public: - //**CastIterator/ConstCastIterator comparison operators***************************************** - // The following comparison operators cannot be defined as namespace or member functions - // but have to be injected into the surrounding scope via the Barton-Nackman trick since - // the template arguments of nested templates cannot be deduced (C++ standard 14.8.2.4/4). - /*!\name CastIterator/ConstCastIterator comparison operators */ - //@{ - - //********************************************************************************************** - /*!\brief Equality comparison between two CastIterator objects. - // - // \param lhs The left hand side cast iterator. - // \param rhs The right hand side cast iterator. - // \return \a true if the iterators point to the same element, \a false if not. - */ - template< typename L, typename R > - friend inline bool operator==( const CastIterator<L>& lhs, const CastIterator<R>& rhs ) - { - return lhs.base() == rhs.base(); - } - //********************************************************************************************** - - //********************************************************************************************** - /*!\brief Equality comparison between a CastIterator and a ConstCastIterator. - // - // \param lhs The left hand side cast iterator. - // \param rhs The right hand side constant cast iterator. - // \return \a true if the iterators point to the same element, \a false if not. - */ - template< typename L, typename R > - friend inline bool operator==( const CastIterator<L>& lhs, const ConstCastIterator<R>& rhs ) - { - return lhs.base() == rhs.base(); - } - //********************************************************************************************** - - //********************************************************************************************** - /*!\brief Equality comparison between a ConstCastIterator and a CastIterator. - // - // \param lhs The left hand side constant cast iterator. - // \param rhs The right hand side cast iterator. - // \return \a true if the iterators point to the same element, \a false if not. - */ - template< typename L, typename R > - friend inline bool operator==( const ConstCastIterator<L>& lhs, const CastIterator<R>& rhs ) - { - return lhs.base() == rhs.base(); - } - //********************************************************************************************** - - //********************************************************************************************** - /*!\brief Equality comparison between two ConstCastIterator objects. - // - // \param lhs The left hand side constant cast iterator. - // \param rhs The right hand side constant cast iterator. - // \return \a true if the iterators point to the same element, \a false if not. - */ - template< typename L, typename R > - friend inline bool operator==( const ConstCastIterator<L>& lhs, const ConstCastIterator<R>& rhs ) - { - return lhs.base() == rhs.base(); - } - //********************************************************************************************** - - //********************************************************************************************** - /*!\brief Inequality comparison between two CastIterator objects. - // - // \param lhs The left hand side cast iterator. - // \param rhs The right hand side cast iterator. - // \return \a true if the iterators don't point to the same element, \a false if they do. - */ - template< typename L, typename R > - friend inline bool operator!=( const CastIterator<L>& lhs, const CastIterator<R>& rhs ) - { - return lhs.base() != rhs.base(); - } - //********************************************************************************************** - - //********************************************************************************************** - /*!\brief Inequality comparison between a CastIterator and a ConstCastIterator. - // - // \param lhs The left hand side cast iterator. - // \param rhs The right hand side constant cast iterator. - // \return \a true if the iterators don't point to the same element, \a false if they do. - */ - template< typename L, typename R > - friend inline bool operator!=( const CastIterator<L>& lhs, const ConstCastIterator<R>& rhs ) - { - return lhs.base() != rhs.base(); - } - //********************************************************************************************** - - //********************************************************************************************** - /*!\brief Inequality comparison between a ConstCastIterator and a CastIterator. - // - // \param lhs The left hand side constant cast iterator. - // \param rhs The right hand side cast iterator. - // \return \a true if the iterators don't point to the same element, \a false if they do. - */ - template< typename L, typename R > - friend inline bool operator!=( const ConstCastIterator<L>& lhs, const CastIterator<R>& rhs ) - { - return lhs.base() != rhs.base(); - } - //********************************************************************************************** - - //********************************************************************************************** - /*!\brief Inequality comparison between two ConstCastIterator objects. - // - // \param lhs The left hand side constant cast iterator. - // \param rhs The right hand side constant cast iterator. - // \return \a true if the iterators don't point to the same element, \a false if they do. - */ - template< typename L, typename R > - friend inline bool operator!=( const ConstCastIterator<L>& lhs, const ConstCastIterator<R>& rhs ) - { - return lhs.base() != rhs.base(); - } - //********************************************************************************************** - - //@} - //********************************************************************************************** -}; -//************************************************************************************************* - - - - -//================================================================================================= -// -// CONSTRUCTORS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Standard constructor for PtrVector. - * - * \param initCapacity The initial capacity of the pointer vector. - * - * The default initial capacity of the pointer vector is specified by the selected growth policy. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline PtrVector<T,D,G>::PtrVector( SizeType initCapacity ) - : size_( 0 ) // Current size of the pointer vector - , capacity_( initCapacity ) // Capacity of the pointer vector - , begin_( new PointerType[initCapacity] ) // Pointer to the first element - , end_( begin_ ) // Pointer to the last element -{} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Copy constructor for PtrVector. - * - * \param pv The pointer vector to be copied. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline PtrVector<T,D,G>::PtrVector( const PtrVector& pv ) - : size_( pv.size_ ) // Current size of the pointer vector - , capacity_( pv.size_ ) // Capacity of the pointer vector - , begin_( new PointerType[capacity_] ) // Pointer to the first element - , end_( begin_+size_ ) // Pointer to the last element -{ - for( SizeType i=0; i<size_; ++i ) - begin_[i] = pv.begin_[i]; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Conversion constructor from different PtrVector instances. - * - * \param pv The pointer vector to be copied. - */ -template< typename T // Type of the pointer vector - , typename D // Deletion policy of the pointer vector - , typename G > // Growth policy of the pointer vector -template< typename T2 // Type of the foreign pointer vector - , typename D2 // Deletion policy of the foreign pointer vector - , typename G2 > // Growth policy of the foreign pointer vector -inline PtrVector<T,D,G>::PtrVector( const PtrVector<T2,D2,G2>& pv ) - : size_( pv.size_ ) // Current size of the pointer vector - , capacity_( pv.size_ ) // Capacity of the pointer vector - , begin_( new PointerType[capacity_] ) // Pointer to the first element - , end_( begin_+size_ ) // Pointer to the last element -{ - for( SizeType i=0; i<size_; ++i ) - begin_[i] = pv.begin_[i]; -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// DESTRUCTOR -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Destructor for PtrVector. - * - * In the destructor, the selected deletion policy is applied to all elements of the pointer - * vector. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline PtrVector<T,D,G>::~PtrVector() -{ - for( PointerType* it=begin_; it!=end_; ++it ) - deleteElement( *it ); - delete [] begin_; -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// ASSIGNMENT OPERATORS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Copy assignment operator for PtrVector. - * - * \param pv The pointer vector to be copied. - * \return Reference to the assigned pointer vector. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -PtrVector<T,D,G>& PtrVector<T,D,G>::operator=( const PtrVector& pv ) -{ - if( &pv == this ) return *this; - - if( pv.size_ > capacity_ ) { - PointerType* newBegin( new PointerType[pv.size_] ); - end_ = std::copy( pv.begin_, pv.end_, newBegin ); - std::swap( begin_, newBegin ); - delete [] newBegin; - - size_ = pv.size_; - capacity_ = pv.size_; - } - else { - end_ = std::copy( pv.begin_, pv.end_, begin_ ); - size_ = pv.size_; - } - - return *this; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Assignment operator for different PtrVector instances. - * - * \param pv The pointer vector to be copied. - * \return Reference to the assigned pointer vector. - */ -template< typename T // Type of the pointer vector - , typename D // Deletion policy of the pointer vector - , typename G > // Growth policy of the pointer vector -template< typename T2 // Type of the foreign pointer vector - , typename D2 // Deletion policy of the foreign pointer vector - , typename G2 > // Growth policy of the foreign pointer vector -PtrVector<T,D,G>& PtrVector<T,D,G>::operator=( const PtrVector<T2,D2,G2>& pv ) -{ - if( pv.size_ > capacity_ ) { - PointerType* newBegin( new PointerType[pv.size_] ); - end_ = std::copy( pv.begin_, pv.end_, newBegin ); - std::swap( begin_, newBegin ); - delete [] newBegin; - - size_ = pv.size_; - capacity_ = pv.size_; - } - else { - end_ = std::copy( pv.begin_, pv.end_, begin_ ); - size_ = pv.size_; - } - - return *this; -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// GET FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Returns the maximum possible size of a pointer vector. - * - * \return The maximum possible size. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline typename PtrVector<T,D,G>::SizeType PtrVector<T,D,G>::maxSize() const -{ - return SizeType(-1) / sizeof(PointerType); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns the current size of the pointer vector. - * - * \return The current size. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline typename PtrVector<T,D,G>::SizeType PtrVector<T,D,G>::size() const -{ - return size_; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns the total number of objects of type \a C contained in the pointer vector. - * - * \return The total number of objects of type \a C. - * - * This function calculates the total number of objects of type \a C within the pointer vector, - * where \a C is a type derived from the type \a T of objects contained in the pointer vector. - * The attempt to use this function for types that are not derived from \a T results in a - * compile time error. - - \code - // Definition of class A and the derived type B - class A { ... }; - class B : public A { ... }; - - // Definition of a pointer vector for class A - typedef PtrVector<A> AVector; - AVector vector; - - AVector::SizeType total = vector.size(); // Calculating the total number of pointers - AVector::SizeType numB = vector.size<B>(); // Calculating the total number of B objects - \endcode - - * \b Note: The total number of objects of type \a C is not cached inside the pointer vector - * but is calculated each time the function is called. Using the templated version of size() - * to calculate the total number objects of type \a C is therefore more expensive than using - * the non-template version of size() to get the total number of pointers in the vector! - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline typename PtrVector<T,D,G>::SizeType PtrVector<T,D,G>::size() const -{ - // The polymorphicCount() function returns the number of objects with dynamic type 'C' - // contained in the range [begin,end). An equivalent code might look like this: - // - // SizeType count( 0 ); - // for( PointerType* it=begin_; it!=end_; ++it ) - // if( dynamic_cast<C*>( *it ) ) ++count; - // return count; - // - // However, the specialization of polymorphicCount() for special type combinations is - // much more efficient (and easier) than the specialization of this function! - return polymorphicCount<C>( begin_, end_ ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns the capacity of the pointer vector. - * - * \return The capacity. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline typename PtrVector<T,D,G>::SizeType PtrVector<T,D,G>::capacity() const -{ - return capacity_; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns \a true if the pointer vector has no elements. - * - * \return \a true if the pointer vector is empty, \a false if it is not. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline bool PtrVector<T,D,G>::isEmpty() const -{ - return size_ == 0; -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// ACCESS FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Subscript operator for the direct access to the pointer vector elements. - * - * \param index Access index. The index has to be in the range \f$[0..size-1]\f$. - * \return Handle to the accessed element. - * - * \b Note: No runtime check is performed to insure the validity of the access index. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline typename PtrVector<T,D,G>::ReferenceType PtrVector<T,D,G>::operator[]( SizeType index ) -{ - return *(begin_+index); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Subscript operator for the direct access to the pointer vector elements. - * - * \param index Access index. The index has to be in the range \f$[0..size-1]\f$. - * \return Handle to the accessed element. - * - * \b Note: No runtime check is performed to insure the validity of the access index. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline typename PtrVector<T,D,G>::ConstReferenceType PtrVector<T,D,G>::operator[]( SizeType index ) const -{ - return *(begin_+index); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns a reference to the first element of the pointer vector. - * - * \return Handle to the first element. - * - * \b Note: No runtime check is performed if the first element exists! - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline typename PtrVector<T,D,G>::ReferenceType PtrVector<T,D,G>::front() -{ - WALBERLA_ASSERT( size_ > 0, "Pointer vector is empty, invalid access to the front element" ); - return *begin_; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns a reference to the first element of the pointer vector. - * - * \return Handle to the first element. - * - * \b Note: No runtime check is performed if the first element exists! - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline typename PtrVector<T,D,G>::ConstReferenceType PtrVector<T,D,G>::front() const -{ - WALBERLA_ASSERT( size_ > 0, "Pointer vector is empty, invalid access to the front element" ); - return *begin_; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns a reference to the last element of the pointer vector. - * - * \return Handle to the last element. - * - * \b Note: No runtime check is performed if the last element exists! - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline typename PtrVector<T,D,G>::ReferenceType PtrVector<T,D,G>::back() -{ - WALBERLA_ASSERT( size_ > 0, "Pointer vector is empty, invalid access to the back element" ); - return *(end_-1); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns a reference to the last element of the pointer vector. - * - * \return Handle to the last element. - * - * \b Note: No runtime check is performed if the last element exists! - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline typename PtrVector<T,D,G>::ConstReferenceType PtrVector<T,D,G>::back() const -{ - WALBERLA_ASSERT( size_ > 0, "Pointer vector is empty, invalid access to the back element" ); - return *(end_-1); -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// ITERATOR FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Returns an iterator to the beginning of the pointer vector. - * - * \return Iterator to the beginning of the pointer vector. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline typename PtrVector<T,D,G>::Iterator PtrVector<T,D,G>::begin() -{ - return Iterator( begin_ ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator to the beginning of the pointer vector. - * - * \return Iterator to the beginning of the pointer vector. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline typename PtrVector<T,D,G>::ConstIterator PtrVector<T,D,G>::begin() const -{ - return ConstIterator( begin_ ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator to the first element of type \a C within the pointer vector. - * - * \return Iterator to the first element of type \a C. - * - * This function returns an iterator to the first element of type \a C within in the pointer - * vector, where \a C is a type derived from the type \a T of objects contained in the pointer - * vector. In case there is no element of type \a C contained in the vector, an iterator just - * past the last element of the pointer vector is returned. In combination with the according - * end function (see example), this iterator allows to iterate over all objects of type \a C - * in the range of the pointer vector. The attempt to use this function for types that are not - * derived from \a T results in a compile time error. - - \code - // Definition of class A and the derived type B - class A { ... }; - class B : public A { ... }; - - // Definition of function f for non-const pointer vectors - void f( PtrVector<A>& vector ) - { - PtrVector<A>::CastIterator<B> begin = vector.begin<B>(); - PtrVector<A>::CastIterator<B> end = vector.end<B>(); - - // Loop over all objects of type B contained in the vector - for( ; begin!=end; ++begin ) - ... - } - - // Definition of function f for const pointer vectors - void f( const PtrVector<A>& vector ) - { - PtrVector<A>::ConstCastIterator<B> begin = vector.begin<B>(); - PtrVector<A>::ConstCastIterator<B> end = vector.end<B>(); - - // Loop over all objects of type B contained in the vector - for( ; begin!=end; ++begin ) - } - \endcode - - * \b Note: Using the templated versions of begin() and end() to traverse all elements of type - * \a C in the element range of the pointer vector is more expensive than using the non-template - * versions to traverse the entire range of elements. Use this function only if you require a - * type-specific member of type \a C. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C> PtrVector<T,D,G>::begin() -{ - return CastIterator<C>( begin_, end_ ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator to the first element of type \a C within the pointer vector. - * - * \return Iterator to the first element of type \a C. - * - * This function returns an iterator to the first element of type \a C within in the pointer - * vector, where \a C is a type derived from the type \a T of objects contained in the pointer - * vector. In case there is no element of type \a C contained in the vector, an iterator just - * past the last element of the pointer vector is returned. In combination with the according - * end function (see example), this iterator allows to iterate over all objects of type \a C - * in the range of the pointer vector. The attempt to use this function for types that are not - * derived from \a T results in a compile time error. - - \code - // Definition of class A and the derived type B - class A { ... }; - class B : public A { ... }; - - // Definition of function f for non-const pointer vectors - void f( PtrVector<A>& vector ) - { - PtrVector<A>::CastIterator<B> begin = vector.begin<B>(); - PtrVector<A>::CastIterator<B> end = vector.end<B>(); - - // Loop over all objects of type B contained in the vector - for( ; begin!=end; ++begin ) - ... - } - - // Definition of function f for const pointer vectors - void f( const PtrVector<A>& vector ) - { - PtrVector<A>::ConstCastIterator<B> begin = vector.begin<B>(); - PtrVector<A>::ConstCastIterator<B> end = vector.end<B>(); - - // Loop over all objects of type B contained in the vector - for( ; begin!=end; ++begin ) - } - \endcode - - * \b Note: Using the templated versions of begin() and end() to traverse all elements of type - * \a C in the element range of the pointer vector is more expensive than using the non-template - * version to traverse the entire range of elements. Use this function only if you require a - * type-specific member of type \a C. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE ConstCastIterator<C> PtrVector<T,D,G>::begin() const -{ - return ConstCastIterator<C>( begin_, end_ ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator just past the last element of the pointer vector. - * - * \return Iterator just past the last element of the pointer vector. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline typename PtrVector<T,D,G>::Iterator PtrVector<T,D,G>::end() -{ - return Iterator( end_ ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator just past the last element of the pointer vector. - * - * \return Iterator just past the last element of the pointer vector. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline typename PtrVector<T,D,G>::ConstIterator PtrVector<T,D,G>::end() const -{ - return ConstIterator( end_ ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator just past the last element of the pointer vector. - * - * \return Iterator just past the last element of the pointer vector. - * - * This function returns an iterator just past the last element of the pointer vector. In - * combination with the according begin function (see example), this iterator allows to iterate - * over all objects of type \a C in the range of the pointer vector. The attempt to use this - * function for types that are not derived from \a T results in a compile time error. - - \code - // Definition of class A and the derived type B - class A { ... }; - class B : public A { ... }; - - // Definition of function f for non-const pointer vectors - void f( PtrVector<A>& vector ) - { - PtrVector<A>::CastIterator<B> begin = vector.begin<B>(); - PtrVector<A>::CastIterator<B> end = vector.end<B>(); - - // Loop over all objects of type B contained in the vector - for( ; begin!=end; ++begin ) - ... - } - - // Definition of function f for const pointer vectors - void f( const PtrVector<A>& vector ) - { - PtrVector<A>::ConstCastIterator<B> begin = vector.begin<B>(); - PtrVector<A>::ConstCastIterator<B> end = vector.end<B>(); - - // Loop over all objects of type B contained in the vector - for( ; begin!=end; ++begin ) - } - \endcode - - * \b Note: Using the templated versions of begin() and end() to traverse all elements of type - * \a C in the element range of the pointer vector is more expensive than using the non-template - * versions to traverse the entire range of elements. Use this function only if you require a - * type-specific member of type \a C. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C> PtrVector<T,D,G>::end() -{ - return CastIterator<C>( end_, end_ ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator just past the last element of the pointer vector. - * - * \return Iterator just past the last element of the pointer vector. - * - * This function returns an iterator just past the last element of the pointer vector. In - * combination with the according begin function (see example), this iterator allows to iterate - * over all objects of type \a C in the range of the pointer vector. The attempt to use this - * function for types that are not derived from \a T results in a compile time error. - - \code - // Definition of class A and the derived type B - class A { ... }; - class B : public A { ... }; - - // Definition of function f for non-const pointer vectors - void f( PtrVector<A>& vector ) - { - PtrVector<A>::CastIterator<B> begin = vector.begin<B>(); - PtrVector<A>::CastIterator<B> end = vector.end<B>(); - - // Loop over all objects of type B contained in the vector - for( ; begin!=end; ++begin ) - ... - } - - // Definition of function f for const pointer vectors - void f( const PtrVector<A>& vector ) - { - PtrVector<A>::ConstCastIterator<B> begin = vector.begin<B>(); - PtrVector<A>::ConstCastIterator<B> end = vector.end<B>(); - - // Loop over all objects of type B contained in the vector - for( ; begin!=end; ++begin ) - } - \endcode - - * \b Note: Using the templated versions of begin() and end() to traverse all elements of type - * \a C in the element range of the pointer vector is more expensive than using the non-template - * version to traverse the entire range of elements. Use this function only if you require a - * type-specific member of type \a C. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE ConstCastIterator<C> PtrVector<T,D,G>::end() const -{ - return ConstCastIterator<C>( end_, end_ ); -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// ELEMENT FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Adding an element to the end of the pointer vector. - * - * \param p The pointer to be added to the end of the pointer vector. - * \return void - * \exception std::length_error Maximum pointer vector length exceeded. - * - * The pushBack function runs in constant time. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline void PtrVector<T,D,G>::pushBack( PointerType p ) -{ - if( size_ != capacity_ ) { - *end_ = p; - ++end_; - ++size_; - } - else { - insert( end_, p ); - } -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Removing an element from the end of the pointer vector. - * - * \return void - * - * This function removes the element at the end of the pointer vector, i.e. the element - * is deleted according to the deletion policy and removed from the vector. Note that in - * case the deletion policy is NoDelete, this function is identical to the releaseBack() - * function. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline void PtrVector<T,D,G>::popBack() -{ - deleteElement( *--end_ ); - --size_; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Releasing the element at the end of the pointer vector. - * - * \return void - * - * This function releases the element at the end of the pointer vector, i.e. the element is - * removed without applying the deletion policy. Therefore the responsibility to delete the - * element is passed to the function caller. Note that in case the deletion policy is NoDelete, - * this function is identical to the popBack() function. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline void PtrVector<T,D,G>::releaseBack() -{ - --end_; - --size_; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Assigning a range of elements to the pointer vector. - * - * \param first Iterator to the first element of the element range. - * \param last Iterator to the element one past the last element of the element range. - * \return void - * \exception std::length_error Maximum pointer vector length exceeded. - * - * This functions assigns the elements in the range \f$ [first,last) \f$ to the pointer vector. - * All elements previously contained in the pointer vector are removed. The assign function runs - * in linear time. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename IteratorType > -inline void PtrVector<T,D,G>::assign( IteratorType first, IteratorType last ) -{ - clear(); - insert( end(), first, last ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Inserting an element into the pointer vector. - * - * \param pos The position before which the element is inserted. - * \param p The pointer to be inserted into the pointer vector. - * \return Iterator to the inserted element. - * \exception std::length_error Maximum pointer vector length exceeded. - * - * The insert function runs in linear time. Note however that inserting elements into a pointer - * vector can be a relatively time-intensive operation. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline typename PtrVector<T,D,G>::Iterator PtrVector<T,D,G>::insert( Iterator pos, PointerType p ) -{ - T** const base = const_cast<T**>( pos.base() ); - const auto diff( base - begin_ ); - - if( size_ != capacity_ && base == end_ ) { - *end_ = p; - ++end_; - ++size_; - } - else { - insert( base, p ); - } - - return Iterator( begin_+diff ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Inserting a range of elements into the pointer vector. - * - * \param pos The position before which the elements are inserted. - * \param first Iterator to the first element of the element range. - * \param last Iterator to the element one past the last element of the element range. - * \return void - * \exception std::length_error Maximum pointer vector length exceeded. - * - * This functions inserts the elements in the range \f$ [first,last) \f$ into the pointer vector. - * The insert function runs in linear time. Note however that inserting elements into a pointer - * vector can be a relatively time-intensive operation. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename IteratorType > -inline void PtrVector<T,D,G>::insert( Iterator pos, IteratorType first, IteratorType last ) -{ - insert( pos, first, last, typename IteratorType::iterator_category() ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*! \cond internal */ -/*!\brief Inserting a range of elements into the pointer vector. - * - * \param pos The position before which the elements are inserted. - * \param first Pointer to the first element of the element range. - * \param last Pointer to the element one past the last element of the element range. - * \return void - * \exception std::length_error Maximum pointer vector length exceeded. - * - * This functions inserts the elements in the range \f$ [first,last) \f$ into the pointer vector. - * The insert function runs in linear time. Note however that inserting elements into a pointer - * vector can be a relatively time-intensive operation. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename IteratorType > -inline void PtrVector<T,D,G>::insert( Iterator pos, IteratorType* first, IteratorType* last ) -{ - insert( pos, first, last, std::random_access_iterator_tag() ); -} -/*! \endcond */ -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Removing an element from the pointer vector. - * - * \param pos The position of the element to be removed. - * \return Iterator to the element after the erased element. - * - * This function erases an element from the pointer vector, i.e. the element is deleted - * according to the deletion policy of the pointer vector and removed from the vector. - * Note that in case the deletion policy is NoDelete, this function is identical to the - * release() function. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline typename PtrVector<T,D,G>::Iterator PtrVector<T,D,G>::erase( Iterator pos ) -{ - T** const base = const_cast<T**>( pos.base() ); - deleteElement( *base ); - std::copy( base+1, end_, base ); - - --size_; - --end_; - - return pos; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Removing an element from the pointer vector. - * - * \param pos The position of the element to be removed. - * \return Iterator to the element after the erased element. - * - * This function erases an element from the pointer vector, i.e. the element is deleted - * according to the deletion policy of the pointer vector and removed from the vector. - * Note that in case the deletion policy is NoDelete, this function is identical to the - * release() function. - * - * Note: The cast iterator \a pos is not invalidated but every other cast iterators including those - * returned by end<C>() are. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C> - PtrVector<T,D,G>::erase( CastIterator<C> pos ) -{ - T** const base = const_cast<T**>( pos.base() ); - deleteElement( *base ); - std::copy( base+1, end_, base ); - - --size_; - --end_; - - return CastIterator<C>( base, end_ ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Releasing an element from the pointer vector. - * - * \param pos The position of the element to be released. - * \return Iterator to the element after the released element. - * - * This function releases an element from the pointer vector, i.e. the element is removed - * without applying the deletion policy. Therefore the responsibility to delete the element - * is passed to the function caller. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline typename PtrVector<T,D,G>::Iterator PtrVector<T,D,G>::release( Iterator pos ) -{ - T** const base = const_cast<T**>( pos.base() ); - std::copy( base+1, end_, base ); - - --size_; - --end_; - - return pos; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Releasing an element from the pointer vector. - * - * \param pos The position of the element to be released. - * \return Iterator to the element after the released element. - * - * This function releases an element from the pointer vector, i.e. the element is removed - * without applying the deletion policy. Therefore the responsibility to delete the element - * is passed to the function caller. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C> - PtrVector<T,D,G>::release( CastIterator<C> pos ) -{ - T** const base = const_cast<T**>( pos.base() ); - std::copy( base+1, end_, base ); - - --size_; - --end_; - - return CastIterator<C>( base, end_ ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Removing all elements from the pointer vector. - * - * \return void - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline void PtrVector<T,D,G>::clear() -{ - for( PointerType* it=begin_; it!=end_; ++it ) - deleteElement( *it ); - - end_ = begin_; - size_ = 0; -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// UTILITY FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Setting the minimum capacity of the pointer vector. - * - * \param newCapacity The new minimum capacity of the pointer vector. - * \return void - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -void PtrVector<T,D,G>::reserve( SizeType newCapacity ) -{ - if( newCapacity > capacity_ ) - { - // Calculating the new capacity - newCapacity = calcCapacity( newCapacity ); - - // Allocating a new array - PointerType* tmp = new PointerType[newCapacity]; - - // Replacing the old array - std::copy( begin_, end_, tmp ); - std::swap( tmp, begin_ ); - capacity_ = newCapacity; - end_ = begin_ + size_; - delete [] tmp; - } -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Swapping the contents of two pointer vectors. - * - * \param pv The pointer vector to be swapped. - * \return void - * \exception no-throw guarantee. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline void PtrVector<T,D,G>::swap( PtrVector& pv ) /* throw() */ -{ - // By using the 'std::swap' function to swap all member variables, - // the function can give the nothrow guarantee. - std::swap( size_, pv.size_ ); - std::swap( capacity_, pv.capacity_ ); - std::swap( begin_, pv.begin_ ); - std::swap( end_, pv.end_ ); -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// HELPER FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Calculating the new capacity of the vector based on its growth policy. - * - * \param minCapacity The minimum necessary capacity. - * \return The new capacity. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline size_t PtrVector<T,D,G>::calcCapacity( size_t minCapacity ) const -{ - WALBERLA_ASSERT( minCapacity > capacity_, "Invalid new vector capacity" ); - const size_t newCapacity( GrowthPolicy()( capacity_, minCapacity ) ); - WALBERLA_ASSERT( newCapacity > capacity_, "Invalid new vector capacity" ); - return newCapacity; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Deleting an element of the pointer vector according to the deletion policy. - * - * \param ptr The element to be deleted. - * \return void - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline void PtrVector<T,D,G>::deleteElement( PointerType ptr ) const -{ - DeletionPolicy()( ptr ); -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// INSERTION HELPER FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Inserting an element into the pointer vector. - * - * \param pos The position before which the element is inserted. - * \param p The pointer to be inserted into the pointer vector. - * \return void - * \exception std::length_error Maximum pointer vector length exceeded. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -void PtrVector<T,D,G>::insert( T**const pos, PointerType p ) -{ - if( size_ != capacity_ ) { - std::copy_backward( pos, end_, end_+1 ); - *pos = p; - ++end_; - ++size_; - } - else if( size_ == maxSize() ) { - throw std::length_error( "Maximum pointer vector length exceeded!" ); - } - else { - SizeType newCapacity( calcCapacity( capacity_+1 ) ); - if( newCapacity > maxSize() || newCapacity < capacity_ ) newCapacity = maxSize(); - - PointerType* newBegin = new PointerType[newCapacity]; - PointerType* newEnd = std::copy( begin_, pos, newBegin ); - *newEnd = p; - ++newEnd; - end_ = std::copy( pos, end_, newEnd ); - - std::swap( newBegin, begin_ ); - delete [] newBegin; - capacity_ = newCapacity; - ++size_; - } -} -//************************************************************************************************* - - -//************************************************************************************************* -/*! \cond internal */ -/*!\brief Inserting a range of elements into the pointer vector. - * - * \param pos The position before which the elements are inserted. - * \param first Iterator to the first element of the element range. - * \param last Iterator to the element one past the last element of the element range. - * \return void - * \exception std::length_error Maximum pointer vector length exceeded. - * - * This functions inserts the elements in the range \f$ [first,last) \f$ into the pointer vector. - * The iterators are treated as input iterators. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename IteratorType > -inline void PtrVector<T,D,G>::insert( Iterator pos, IteratorType first, IteratorType last, - std::input_iterator_tag ) -{ - for( ; first!=last; ++first ) { - pos = insert( pos, *first ); - ++pos; - } -} -/*! \endcond */ -//************************************************************************************************* - - -//************************************************************************************************* -/*! \cond internal */ -/*!\brief Inserting a range of elements into the pointer vector. - * - * \param pos The position before which the elements are inserted. - * \param first Iterator to the first element of the element range. - * \param last Iterator to the element one past the last element of the element range. - * \return void - * \exception std::length_error Maximum pointer vector length exceeded. - * - * This functions inserts the elements in the range \f$ [first,last) \f$ into the pointer vector. - * The iterators are treated as random access iterators. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename IteratorType > -inline void PtrVector<T,D,G>::insert( Iterator pos, IteratorType first, IteratorType last, - std::random_access_iterator_tag ) -{ - T** const base = const_cast<T**>( pos.base() ); - const SizeType diff( last - first ); - - if( size_+diff <= capacity_ && base == end_ ) { - for( ; first!=last; ++first, ++end_ ) { - *end_ = *first; - } - size_ += diff; - } - else { - insert( base, first, last, diff ); - } -} -/*! \endcond */ -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Inserting a range of elements into the pointer vector. - * - * \param pos The position before which the elements are inserted. - * \param first Iterator to the first element of the element range. - * \param last Iterator to the element one past the last element of the element range. - * \param n The number of elements to be inserted. - * \return void - * \exception std::length_error Maximum pointer vector length exceeded. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename IteratorType > -void PtrVector<T,D,G>::insert( T** pos, IteratorType first, IteratorType last, SizeType n ) -{ - const SizeType newSize( size_ + n ); - - if( newSize <= capacity_ ) { - std::copy_backward( pos, end_, end_+n ); - for( ; first!=last; ++first, ++pos ) { - *pos = *first; - } - end_ += n; - size_ = newSize; - } - else if( newSize > maxSize() || newSize < size_ ) { - throw std::length_error( "Maximum pointer vector length exceeded!" ); - } - else { - PointerType* newBegin = new PointerType[newSize]; - PointerType* newEnd = std::copy( begin_, pos, newBegin ); - - for( ; first!=last; ++first, ++newEnd ) { - *newEnd = *first; - } - - end_ = std::copy( pos, end_, newEnd ); - - std::swap( newBegin, begin_ ); - delete [] newBegin; - capacity_ = newSize; - size_ = newSize; - } -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// GLOBAL OPERATORS -// -//================================================================================================= - -//************************************************************************************************* -/*!\name PtrVector operators */ -//@{ -template< typename T, typename D, typename G > -inline bool operator==( const PtrVector<T,D,G>& lhs, const PtrVector<T,D,G>& rhs ); - -template< typename T, typename D, typename G > -inline bool operator!=( const PtrVector<T,D,G>& lhs, const PtrVector<T,D,G>& rhs ); - -template< typename T, typename D, typename G > -inline void swap( PtrVector<T,D,G>& a, PtrVector<T,D,G>& b ) /* throw() */; -//@} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Equality comparison between two pointer vectors. - * - * \param lhs The left hand side pointer vector. - * \param rhs The right hand side pointer vector. - * \return \a true if the two pointer vectors are equal, \a false if they are not. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline bool operator==( const PtrVector<T,D,G>& lhs, const PtrVector<T,D,G>& rhs ) -{ - return lhs.size() == rhs.size() && std::equal( lhs.begin(), lhs.end(), rhs.begin() ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Inequality comparison between two pointer vectors. - * - * \param lhs The left hand side pointer vector. - * \param rhs The right hand side pointer vector. - * \return \a true if the two pointer vectors are inequal, \a false if they are not. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline bool operator!=( const PtrVector<T,D,G>& lhs, const PtrVector<T,D,G>& rhs ) -{ - return lhs.size() != rhs.size() || !std::equal( lhs.begin(), lhs.end(), rhs.begin() ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Swapping the contents of two pointer vectors. - * - * \param a The first pointer vector to be swapped. - * \param b The second pointer vector to be swapped. - * \return void - * \exception no-throw guarantee. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -inline void swap( PtrVector<T,D,G>& a, PtrVector<T,D,G>& b ) /* throw() */ -{ - a.swap( b ); -} -//************************************************************************************************* - - - - - - - - -//================================================================================================= -// -// NESTED CLASS PTRVECTOR::CASTITERATOR -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Dynamic cast iterator for polymorphic pointer vectors. - * \ingroup util - * - * The CastIterator class is part of the PtrVector class and represent a forward iterator - * over all elements of type \a C contained in a range of elements of type \a T, where \a C - * is a type derived from \a T. - - \code - class A { ... }; - class B : public class A { ... }; - - PtrVector<A>::CastIterator<B> begin; - PtrVector<A>::CastIterator<B> end; - - // Loop over all elements of type B within the range [begin..end) - for( ; begin!=end; ++begin ) - ... - \endcode - - * \b Note: Using a CastIterator is computationally more expensive than using a standard - * iterator over all elements contained in the vector. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -class PtrVector<T,D,G>::CastIterator -{ -public: - //**Type definitions**************************************************************************** - // pe naming convention - typedef std::forward_iterator_tag IteratorCategory; //!< The iterator category. - typedef C* ValueType; //!< Type of the underlying pointers. - typedef C* PointerType; //!< Pointer return type. - typedef C* const& ReferenceType; //!< Reference return type. - typedef ptrdiff_t DifferenceType; //!< Difference between two iterators. - typedef T* const* IteratorType; //!< Type of the internal pointer. - - // STL iterator requirements - typedef IteratorCategory iterator_category; //!< The iterator category. - typedef ValueType value_type; //!< Type of the underlying pointers. - typedef PointerType pointer; //!< Pointer return type. - typedef ReferenceType reference; //!< Reference return type. - typedef DifferenceType difference_type; //!< Difference between two iterators. - //********************************************************************************************** - - //**Constructors******************************************************************************** - /*!\name Constructors */ - //@{ - inline CastIterator(); - inline CastIterator( IteratorType begin, IteratorType end ); - - template< typename Other > - inline CastIterator( const CastIterator<Other>& it ); - - // No explicitly declared copy constructor. - //@} - //********************************************************************************************** - - //**Destructor********************************************************************************** - // No explicitly declared destructor. - //********************************************************************************************** - - //**Copy assignment operator******************************************************************** - // No explicitly declared copy assignment operator. - //********************************************************************************************** - - //**Operators*********************************************************************************** - /*!\name Operators */ - //@{ - inline CastIterator& operator++(); - inline CastIterator operator++( int ); - //@} - //********************************************************************************************** - - //**Access operators**************************************************************************** - /*!\name Access operators */ - //@{ - inline PointerType operator*() const; - inline PointerType operator->() const; - //@} - //********************************************************************************************** - - //**Utility functions*************************************************************************** - /*!\name Utility functions */ - //@{ - inline const IteratorType& base() const; - inline const IteratorType& stop() const; - //@} - //********************************************************************************************** - -private: - //**Member variables**************************************************************************** - /*!\name Member variables */ - //@{ - IteratorType cur_; //!< Pointer to the current memory location. - IteratorType end_; //!< Pointer to the element one past the last element in the element range. - //@} - //********************************************************************************************** -}; -//************************************************************************************************* - - - - -//================================================================================================= -// -// CONSTRUCTOR -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Default constructor for CastIterator. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline PtrVector<T,D,G>::CastIterator<C>::CastIterator() - : cur_(NULL) // Pointer to the current memory location - , end_(NULL) // Pointer to the element one past the last element in the element range -{ - static_assert(boost::is_base_of<T, C>::value && !boost::is_base_of<C, T>::value, "C has to be strictly derived from T"); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Standard constructor for CastIterator. - * - * \param begin The beginning of the element range. - * \param end The end of the element range. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline PtrVector<T,D,G>::CastIterator<C>::CastIterator( IteratorType begin, IteratorType end ) - : cur_(begin) // Pointer to the current memory location - , end_(end) // Pointer to the element one past the last element in the element range -{ - static_assert(boost::is_base_of<T, C>::value && !boost::is_base_of<C, T>::value, "C has to be strictly derived from T"); - // The polymorphicFind() function finds the next pointer to an object with dynamic type 'C' - // contained in the range [cur_,end). An equivalent code might look like this: - // - // while( cur_ != end_ && !dynamic_cast<C*>( *cur_ ) ) ++cur_; - // - // However, the specialization of polymorphicFind() for special type combinations is much - // more efficient (and way easier!) than the specialization of this function! - cur_ = polymorphicFind<C>( cur_, end_ ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Conversion constructor from different CastIterator instances. - * - * \param it The foreign CastIterator instance to be copied. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -template< typename Other > // The foreign cast iterator type -inline PtrVector<T,D,G>::CastIterator<C>::CastIterator( const CastIterator<Other>& it ) - : cur_( it.base() ) // Pointer to the current memory location - , end_( it.stop() ) // Pointer to the element one past the last element in the element range -{ - static_assert(boost::is_base_of<C, T>::value && !boost::is_base_of<C, T>::value, "C has to be strictly derived from T"); - static_assert(boost::is_convertible<Other*, C*>::value, "Other must be convertible to C" ); -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// OPERATORS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Pre-increment operator. - * - * \return Reference to the incremented cast iterator. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C>& - PtrVector<T,D,G>::CastIterator<C>::operator++() -{ - // The polymorphicFind() function finds the next pointer to an object with dynamic type 'C' - // contained in the range [cur_+1,end). An equivalent code might look like this: - // - // while( ++cur_ != end_ && !dynamic_cast<C*>( *cur_ ) ) {} - // - // However, the specialization of polymorphicFind() for special type combinations is much - // more efficient (and way easier!) than the specialization of this function! - cur_ = polymorphicFind<C>( ++cur_, end_ ); - - return *this; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Post-increment operator. - * - * \return The incremented cast iterator. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C> - PtrVector<T,D,G>::CastIterator<C>::operator++( int ) -{ - CastIterator tmp( *this ); - - // The polymorphicFind() function finds the next pointer to an object with dynamic type 'C' - // contained in the range [cur_+1,end). An equivalent code might look like this: - // - // while( ++cur_ != end_ && !dynamic_cast<C*>( *cur_ ) ) {} - // - // However, the specialization of polymorphicFind() for special type combinations is much - // more efficient (and way easier!) than the specialization of this function! - cur_ = polymorphicFind<C>( ++cur_, end_ ); - - return tmp; -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// ACCESS OPERATORS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Returns a handle to the element at the current iterator position. - * - * \return Handle to the element at the current iterator position. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C>::PointerType - PtrVector<T,D,G>::CastIterator<C>::operator*() const -{ - return static_cast<C*>( *cur_ ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Direct access to the element at the current iterator position. - * - * \return Reference to the element at the current iterator position. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C>::PointerType - PtrVector<T,D,G>::CastIterator<C>::operator->() const -{ - return static_cast<C*>( *cur_ ); -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// UTILITY FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Direct access to the current memory location of the cast iterator. - * - * \return Pointer to the current memory location. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline const typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C>::IteratorType& - PtrVector<T,D,G>::CastIterator<C>::base() const -{ - return cur_; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Direct access to the final memory location of the cast iterator. - * - * \return Pointer to the final memory location. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline const typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C>::IteratorType& - PtrVector<T,D,G>::CastIterator<C>::stop() const -{ - return end_; -} -//************************************************************************************************* - - - - - - - - -//================================================================================================= -// -// NESTED CLASS PTRVECTOR::CONSTCASTITERATOR -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Dynamic cast iterator for polymorphic pointer vectors. - * \ingroup util - * - * The ConstCastIterator class is part of the PtrVector class and represent a forward iterator - * over all elements of type \a C contained in a range of elements of type \a T, where \a C - * is a type derived from \a T. The ConstCastIterator is the counterpart of CastIterator for - * constant vectors. - - \code - class A { ... }; - class B : public class A { ... }; - - PtrVector<A>::ConstCastIterator<B> begin; - PtrVector<A>::ConstCastIterator<B> end; - - // Loop over all elements of type B within the range [begin..end) - for( ; begin!=end; ++begin ) - ... - \endcode - - * \b Note: Using a ConstCastIterator is computationally more expensive than using a standard - * iterator over all elements contained in the vector. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -class PtrVector<T,D,G>::ConstCastIterator -{ -public: - //**Type definitions**************************************************************************** - // pe naming convention - typedef std::forward_iterator_tag IteratorCategory; //!< The iterator category. - typedef const C* ValueType; //!< Type of the underlying pointers. - typedef const C* PointerType; //!< Pointer return type. - typedef const C* const& ReferenceType; //!< Reference return type. - typedef ptrdiff_t DifferenceType; //!< Difference between two iterators. - typedef const T* const* IteratorType; //!< Type of the internal pointer. - - // STL iterator requirements - typedef IteratorCategory iterator_category; //!< The iterator category. - typedef ValueType value_type; //!< Type of the underlying pointers. - typedef PointerType pointer; //!< Pointer return type. - typedef ReferenceType reference; //!< Reference return type. - typedef DifferenceType difference_type; //!< Difference between two iterators. - //********************************************************************************************** - - //**Constructors******************************************************************************** - /*!\name Constructors */ - //@{ - inline ConstCastIterator(); - inline ConstCastIterator( IteratorType begin, IteratorType end ); - - template< typename Other > - inline ConstCastIterator( const ConstCastIterator<Other>& it ); - - template< typename Other > - inline ConstCastIterator( const typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<Other>& it ); - - // No explicitly declared copy constructor. - //@} - //********************************************************************************************** - - //**Destructor********************************************************************************** - // No explicitly declared destructor. - //********************************************************************************************** - - //**Copy assignment operator******************************************************************** - // No explicitly declared copy assignment operator. - //********************************************************************************************** - - //**Operators*********************************************************************************** - /*!\name Operators */ - //@{ - inline ConstCastIterator& operator++(); - inline ConstCastIterator operator++( int ); - //@} - //********************************************************************************************** - - //**Access operators**************************************************************************** - /*!\name Access operators */ - //@{ - inline PointerType operator*() const; - inline PointerType operator->() const; - //@} - //********************************************************************************************** - - //**Utility functions*************************************************************************** - /*!\name Utility functions */ - //@{ - inline const IteratorType& base() const; - inline const IteratorType& stop() const; - //@} - //********************************************************************************************** - -private: - //**Member variables**************************************************************************** - /*!\name Member variables */ - //@{ - IteratorType cur_; //!< Pointer to the current memory location. - IteratorType end_; //!< Pointer to the element one past the last element in the element range. - //@} - //********************************************************************************************** -}; -//************************************************************************************************* - - - - -//================================================================================================= -// -// CONSTRUCTOR -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Default constructor for ConstCastIterator. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline PtrVector<T,D,G>::ConstCastIterator<C>::ConstCastIterator() - : cur_(NULL) // Pointer to the current memory location - , end_(NULL) // Pointer to the element one past the last element in the element range -{ - static_assert(boost::is_base_of<C, T>::value && !boost::is_base_of<C, T>::value, "C has to be strictly derived from T"); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Standard constructor for ConstCastIterator. - * - * \param begin The beginning of the element range. - * \param end The end of the element range. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline PtrVector<T,D,G>::ConstCastIterator<C>::ConstCastIterator( IteratorType begin, IteratorType end ) - : cur_(begin) // Pointer to the current memory location - , end_(end) // Pointer to the element one past the last element in the element range -{ - // The polymorphicFind() function finds the next pointer to an object with dynamic type 'C' - // contained in the range [cur_,end). An equivalent code might look like this: - // - // while( cur_ != end_ && !dynamic_cast<C*>( *cur_ ) ) ++cur_; - // - // However, the specialization of polymorphicFind() for special type combinations is much - // more efficient (and way easier!) than the specialization of this function! - cur_ = polymorphicFind<C>( cur_, end_ ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Conversion constructor from different ConstCastIterator instances. - * - * \param it The foreign ConstCastIterator instance to be copied. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -template< typename Other > // The foreign constant cast iterator type -inline PtrVector<T,D,G>::ConstCastIterator<C>::ConstCastIterator( const ConstCastIterator<Other>& it ) - : cur_( it.base() ) // Pointer to the current memory location - , end_( it.stop() ) // Pointer to the element one past the last element in the element range -{ - static_assert(boost::is_base_of<C, T>::value && !boost::is_base_of<C, T>::value, "C has to be strictly derived from T"); - static_assert(boost::is_convertible<Other*, C*>::value, "Other must be convertible to C" ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Conversion constructor from CastIterator instances. - * - * \param it The foreign CastIterator instance to be copied. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -template< typename Other > // The foreign cast iterator type -inline PtrVector<T,D,G>::ConstCastIterator<C>::ConstCastIterator( const typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<Other>& it ) - : cur_( it.base() ) // Pointer to the current memory location - , end_( it.stop() ) // Pointer to the element one past the last element in the element range -{ - static_assert(boost::is_base_of<C, T>::value && !boost::is_base_of<C, T>::value, "C has to be strictly derived from T"); - static_assert(boost::is_convertible<Other*, C*>::value, "Other must be convertible to C" ); -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// OPERATORS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Pre-increment operator. - * - * \return Reference to the incremented cast iterator. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE ConstCastIterator<C>& - PtrVector<T,D,G>::ConstCastIterator<C>::operator++() -{ - // The polymorphicFind() function finds the next pointer to an object with dynamic type 'C' - // contained in the range [cur_+1,end). An equivalent code might look like this: - // - // while( ++cur_ != end_ && !dynamic_cast<const C*>( *cur_ ) ) {} - // - // However, the specialization of polymorphicFind() for special type combinations is much - // more efficient (and way easier!) than the specialization of this function! - cur_ = polymorphicFind<const C>( ++cur_, end_ ); - - return *this; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Post-increment operator. - * - * \return The incremented cast iterator. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE ConstCastIterator<C> - PtrVector<T,D,G>::ConstCastIterator<C>::operator++( int ) -{ - ConstCastIterator tmp( *this ); - - // The polymorphicFind() function finds the next pointer to an object with dynamic type 'C' - // contained in the range [cur_+1,end). An equivalent code might look like this: - // - // while( ++cur_ != end_ && !dynamic_cast<const C*>( *cur_ ) ) {} - // - // However, the specialization of polymorphicFind() for special type combinations is much - // more efficient (and way easier!) than the specialization of this function! - cur_ = polymorphicFind<const C>( ++cur_, end_ ); - - return tmp; -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// ACCESS OPERATORS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Returns a handle to the element at the current iterator position. - * - * \return Handle to the element at the current iterator position. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE ConstCastIterator<C>::PointerType - PtrVector<T,D,G>::ConstCastIterator<C>::operator*() const -{ - return static_cast<const C*>( *cur_ ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Direct access to the element at the current iterator position. - * - * \return Reference to the element at the current iterator position. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE ConstCastIterator<C>::PointerType - PtrVector<T,D,G>::ConstCastIterator<C>::operator->() const -{ - return static_cast<const C*>( *cur_ ); -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// UTILITY FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Direct access to the current memory location of the constant cast iterator. - * - * \return Pointer to the current memory location. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline const typename PtrVector<T,D,G>::WALBERLA_TEMPLATE ConstCastIterator<C>::IteratorType& - PtrVector<T,D,G>::ConstCastIterator<C>::base() const -{ - return cur_; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Direct access to the final memory location of the constant cast iterator. - * - * \return Pointer to the final memory location. - */ -template< typename T // Type - , typename D // Deletion policy - , typename G > // Growth policy -template< typename C > // Cast type -inline const typename PtrVector<T,D,G>::WALBERLA_TEMPLATE ConstCastIterator<C>::IteratorType& - PtrVector<T,D,G>::ConstCastIterator<C>::stop() const -{ - return end_; -} -//************************************************************************************************* -} diff --git a/src/core/ptrvector/policies/ArrayDelete.h b/src/core/ptrvector/policies/ArrayDelete.h deleted file mode 100644 index bf6b605abc8d82a6612b9943aa596ba4fbb2bae6..0000000000000000000000000000000000000000 --- a/src/core/ptrvector/policies/ArrayDelete.h +++ /dev/null @@ -1,88 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file ArrayDelete.h -//! \ingroup core -//! \author Klaus Iglberger -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -// -//====================================================================================================================== - -#pragma once - - -//************************************************************************************************* -// Includes -//************************************************************************************************* - -#include <boost/checked_delete.hpp> - -namespace walberla { - -//================================================================================================= -// -// CLASS DEFINITION -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Array-delete policy class. - * \ingroup util - * - * The ArrayDelete policy functor class applies an array delete operation to the given argument. - * Note that the array delete operation is NOT permitted for inclomplete types (i.e. declared - * but undefined data types). The attempt to apply an ArrayDelete functor to a pointer to an - * array of objects of incomplete type results in a compile time error! - */ -struct ArrayDelete -{ - //**Utility functions*************************************************************************** - /*!\name Utility functions */ - //@{ - template< typename Type > - inline void operator()( Type ptr ) const; - //@} - //********************************************************************************************** -}; -//************************************************************************************************* - - - - -//================================================================================================= -// -// UTILITY FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Implementation of the array-delete policy. - * - * \param ptr The pointer to the array to be deleted. - * \return void - * - * This function applies an array delete operation to the given argument. Note that the array - * delete operation is NOT permitted for inclomplete types (i.e. declared but undefined data - * types). The attempt to use this function for a pointer to an array of objects of incomplete - * type results in a compile time error! - */ -template< typename Type > -inline void ArrayDelete::operator()( Type ptr ) const -{ - boost::checked_array_delete( ptr ); -} -//************************************************************************************************* - -} // namespace diff --git a/src/core/ptrvector/policies/ConstantGrowth.h b/src/core/ptrvector/policies/ConstantGrowth.h deleted file mode 100644 index 2d20250ca78ac865eac5a1d362c35258f28ddaf2..0000000000000000000000000000000000000000 --- a/src/core/ptrvector/policies/ConstantGrowth.h +++ /dev/null @@ -1,94 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file ConstantGrowth.h -//! \ingroup core -//! \author Klaus Iglberger -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -// -//====================================================================================================================== - -#pragma once - -#include <core/DataTypes.h> - -//************************************************************************************************* -// Includes -//************************************************************************************************* - -namespace walberla { - -//================================================================================================= -// -// CLASS DEFINITION -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Constant growth policy class. - * \ingroup util - * - * The ConstantGrowth policy class implements a constant growth strategy. It can be customized - * for any purpose: the \a Growth template argument specifies the constant increase of the given - * size. - */ -template< size_t Growth > -struct ConstantGrowth -{ - //**Utility functions*************************************************************************** - /*!\name Utility functions */ - //@{ - inline size_t operator()( size_t oldSize, size_t minSize ) const; - //@} - //********************************************************************************************** -}; -//************************************************************************************************* - - -//************************************************************************************************* -/*! \cond internal */ -/*!\brief Specialization of the constant growth policy for 0 growth. - * \ingroup util - */ -template<> -struct ConstantGrowth<0>; -/*! \endcond */ -//************************************************************************************************* - - - - -//================================================================================================= -// -// UTILITY FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Returns a new size depending on the given old size and the required minimum size. - * - * \param old The old size. - * \param minimum The required minimum size. - * \return The new size (at least the required minimum size). - */ -template< size_t Growth > -inline size_t ConstantGrowth<Growth>::operator()( size_t old, size_t minimum ) const -{ - const size_t needed( math::max<size_t>( old+Growth, minimum ) ); - return ( ( needed )?( 4 * ( (needed-1)/4+1 ) ):( 0 ) ); -} -//************************************************************************************************* - -} // namespace diff --git a/src/core/ptrvector/policies/LinearGrowth.h b/src/core/ptrvector/policies/LinearGrowth.h deleted file mode 100644 index 314b79380525dda287747d986be18a28a15010c4..0000000000000000000000000000000000000000 --- a/src/core/ptrvector/policies/LinearGrowth.h +++ /dev/null @@ -1,106 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file LinearGrowth.h -//! \ingroup core -//! \author Klaus Iglberger -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -// -//====================================================================================================================== - -#pragma once - - -//************************************************************************************************* -// Includes -//************************************************************************************************* - -#include <core/math/Utility.h> -#include <core/DataTypes.h> - -namespace walberla { - -//================================================================================================= -// -// CLASS DEFINITION -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Linear growth policy class. - * \ingroup util - * - * The LinearGrowth policy class implements a linear growth strategy. It can be customized for - * any purpose: the \a Growth template argument specifies the factor of the size growth. - */ -template< size_t Growth > -struct LinearGrowth -{ - //**Utility functions*************************************************************************** - /*!\name Utility functions */ - //@{ - inline size_t operator()( size_t oldSize, size_t minSize ) const; - //@} - //********************************************************************************************** -}; -//************************************************************************************************* - - -//************************************************************************************************* -/*! \cond internal */ -/*!\brief Specialization of the linear growth policy for 0 growth. - * \ingroup util - */ -template<> -struct LinearGrowth<0>; -/*! \endcond */ -//************************************************************************************************* - - -//************************************************************************************************* -/*! \cond internal */ -/*!\brief Specialization of the linear growth policy for 1 growth. - * \ingroup util - */ -template<> -struct LinearGrowth<1>; -/*! \endcond */ -//************************************************************************************************* - - - - -//================================================================================================= -// -// UTILITY FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Returns a new size depending on the given old size and the required minimum size. - * - * \param old The old size. - * \param minimum The required minimum size. - * \return The new size (at least the required minimum size). - */ -template< size_t Growth > -inline size_t LinearGrowth<Growth>::operator()( size_t old, size_t minimum ) const -{ - const size_t needed( math::max<size_t>( old*Growth, minimum ) ); - return ( ( needed )?( 4 * ( (needed-1)/4+1 ) ):( 0 ) ); -} -//************************************************************************************************* - -} // namespace diff --git a/src/core/ptrvector/policies/NoDelete.h b/src/core/ptrvector/policies/NoDelete.h deleted file mode 100644 index 14b24aae3c1b48891a0b39ed02be7366b7d6a978..0000000000000000000000000000000000000000 --- a/src/core/ptrvector/policies/NoDelete.h +++ /dev/null @@ -1,69 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file NoDelete.h -//! \ingroup core -//! \author Klaus Iglberger -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -// -//====================================================================================================================== - -#pragma once - -namespace walberla { - -//================================================================================================= -// -// CLASS DEFINITION -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief No-delete policy class. - * \ingroup util - */ -struct NoDelete -{ - //**Utility functions*************************************************************************** - /*!\name Utility functions */ - //@{ - template< typename Type > - inline void operator()( const Type& ptr ) const; - //@} - //********************************************************************************************** -}; -//************************************************************************************************* - - - - -//================================================================================================= -// -// UTILITY FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Implementation of the no-delete policy. - * - * \param ptr The pointer to delete. - * \return void - */ -template< typename Type > -inline void NoDelete::operator()( const Type& /*ptr*/ ) const -{} -//************************************************************************************************* - -} // namespace diff --git a/src/core/ptrvector/policies/OptimalGrowth.h b/src/core/ptrvector/policies/OptimalGrowth.h deleted file mode 100644 index 59abed396b4ac6dccb2a35077f49f085e465c3c7..0000000000000000000000000000000000000000 --- a/src/core/ptrvector/policies/OptimalGrowth.h +++ /dev/null @@ -1,85 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file OptimalGrowth.h -//! \ingroup core -//! \author Klaus Iglberger -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -// -//====================================================================================================================== - -#pragma once - - -//************************************************************************************************* -// Includes -//************************************************************************************************* - -#include <core/math/Utility.h> -#include <core/DataTypes.h> - -namespace walberla { - -//================================================================================================= -// -// CLASS DEFINITION -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Optimal growth policy class. - * \ingroup util - * - * The OptimalGrowth policy class implements the optimal growth strategy suggested by Andrew - * Koenig for the std::vector class (see Andrew Koenig's column in the September 1998 issue of - * JOOP (Journal of Object-Oriented Programming), or the Dr. Dobb's article 'C++ Made Easier: - * How Vectors Grow', 2001). It applies an exponential growth strategy using a factor of 1.5 - * and additionally ensures that the sizes returns are always multiples of four. - */ -struct OptimalGrowth -{ - //**Utility functions*************************************************************************** - /*!\name Utility functions */ - //@{ - inline size_t operator()( size_t oldSize, size_t minSize ) const; - //@} - //********************************************************************************************** -}; -//************************************************************************************************* - - - - -//================================================================================================= -// -// UTILITY FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Returns a new size depending on the given old size and the required minimum size. - * - * \param old The old size. - * \param minimum The required minimum size. - * \return The new size (at least the required minimum size). - */ -inline size_t OptimalGrowth::operator()( size_t old, size_t minimum ) const -{ - const size_t needed( math::max( static_cast<size_t>( real_c(old)*1.5 ), minimum ) ); - return ( ( needed )?( 4 * ( (needed-1)/4 + 1 ) ):( 0 ) ); -} -//************************************************************************************************* - -} // namespace diff --git a/src/core/ptrvector/policies/PtrDelete.h b/src/core/ptrvector/policies/PtrDelete.h deleted file mode 100644 index 1940275e2ece96848af8982873160b8bb41c7cd8..0000000000000000000000000000000000000000 --- a/src/core/ptrvector/policies/PtrDelete.h +++ /dev/null @@ -1,88 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file PtrDelete.h -//! \ingroup core -//! \author Klaus Iglberger -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -// -//====================================================================================================================== - -#pragma once - - -//************************************************************************************************* -// Includes -//************************************************************************************************* - -#include <boost/checked_delete.hpp> - -namespace walberla { - -//================================================================================================= -// -// CLASS DEFINITION -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Pointer-delete policy class. - * \ingroup util - * - * The PtrDelete policy functor class applies a delete operation to the given argument. Note that - * the delete operation is NOT permitted for inclomplete types (i.e. declared but undefined data - * types). The attempt to apply a PtrDelete functor to a pointer to an object of incomplete type - * results in a compile time error! - */ -struct PtrDelete -{ - //**Utility functions*************************************************************************** - /*!\name Utility functions */ - //@{ - template< typename Type > - inline void operator()( Type ptr ) const; - //@} - //********************************************************************************************** -}; -//************************************************************************************************* - - - - -//================================================================================================= -// -// UTILITY FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Implementation of the pointer-delete policy. - * - * \param ptr The pointer to delete. - * \return void - * - * This function applies a standard delete operation to the given argument. Note that the delete - * operation is NOT permitted for inclomplete types (i.e. declared but undefined data types). The - * attempt to use this function for a pointer to an object of incomplete type results in a compile - * time error! - */ -template< typename Type > -inline void PtrDelete::operator()( Type ptr ) const -{ - boost::checked_delete( ptr ); -} -//************************************************************************************************* - -} // namespace diff --git a/src/core/timing/TimingNode.h b/src/core/timing/TimingNode.h index 8ec0b3338a810f8618ff790e550329698096fd60..2f0597f7a591b12907932942e76f107b4f90015d 100644 --- a/src/core/timing/TimingNode.h +++ b/src/core/timing/TimingNode.h @@ -26,6 +26,7 @@ #include "core/debug/Debug.h" #include "core/logging/Logging.h" +#include "core/mpi/Gatherv.h" #include "core/mpi/MPIManager.h" #include "core/mpi/Reduce.h" #include "core/mpi/SetReduction.h" @@ -253,6 +254,20 @@ void reduceInplace( TimingNode<TP>& tn, ReduceType rt = REDUCE_TOTAL, int target break; } + WALBERLA_ASSERT_EQUAL(vals.size(), valsSq.size()); + WALBERLA_ASSERT_EQUAL(vals.size(), min.size()); + WALBERLA_ASSERT_EQUAL(vals.size(), max.size()); + WALBERLA_ASSERT_EQUAL(vals.size(), count.size()); + + WALBERLA_DEBUG_SECTION() + { + //checking if all timing trees contain the same number of elements + std::vector<uint32_t> lens; + lens.push_back(uint32_c(vals.size())); + lens = mpi::allGatherv(lens); + std::for_each(lens.begin(), lens.end(), [&](const uint32_t& v){WALBERLA_UNUSED(v); WALBERLA_ASSERT_EQUAL( v, vals.size(), "Different number of TimingTree nodes detected! All TimingTrees need to have the same timers for reduction!");}); + } + // Target vectors where reduced values are stored std::vector<double> minRed; std::vector<double> maxRed; diff --git a/src/cuda/AddGPUFieldToStorage.impl.h b/src/cuda/AddGPUFieldToStorage.impl.h index 03b90c728fe345259079ee7c67c176eec9ff64dc..1befc3e81bc4a04fd89c1ec9561e1e417023cc05 100644 --- a/src/cuda/AddGPUFieldToStorage.impl.h +++ b/src/cuda/AddGPUFieldToStorage.impl.h @@ -73,7 +73,7 @@ namespace cuda { uint_t nrOfGhostLayers, bool usePitchedMem ) { - auto func = boost::bind ( internal::createGPUField<GPUField_T>, _1, _2, nrOfGhostLayers, fSize, layout, usePitchedMem ); + auto func = std::bind ( internal::createGPUField<GPUField_T>, std::placeholders::_1, std::placeholders::_2, nrOfGhostLayers, fSize, layout, usePitchedMem ); return bs->addStructuredBlockData< GPUField_T >( func, identifier ); } @@ -84,7 +84,7 @@ namespace cuda { const std::string & identifier, bool usePitchedMem ) { - auto func = boost::bind ( internal::createGPUFieldFromCPUField<Field_T>, _1, _2, cpuFieldID, usePitchedMem ); + auto func = std::bind ( internal::createGPUFieldFromCPUField<Field_T>, std::placeholders::_1, std::placeholders::_2, cpuFieldID, usePitchedMem ); return bs->addStructuredBlockData< GPUField<typename Field_T::value_type> >( func, identifier ); } diff --git a/src/cuda/FieldCopy.h b/src/cuda/FieldCopy.h index 07fd04c808032fccd21c3f00f98600294b124a9b..4f13fa999ffec19249183fecd2a4fe0939e2674e 100644 --- a/src/cuda/FieldCopy.h +++ b/src/cuda/FieldCopy.h @@ -52,7 +52,7 @@ namespace cuda { std::function<void()> fieldCpyFunctor( const shared_ptr< StructuredBlockStorage > & blocks, BlockDataID dstID, ConstBlockDataID srcID ) { - return boost::bind( fieldCpy<DstType,SrcType>, blocks, dstID, srcID ); + return std::bind( fieldCpy<DstType,SrcType>, blocks, dstID, srcID ); } @@ -68,7 +68,7 @@ namespace cuda { template<typename DstType, typename SrcType> std::function<void(IBlock*)> fieldCpyFunctor( BlockDataID dstID, ConstBlockDataID srcID ) { - return boost::bind( fieldCpySweepFunction<DstType,SrcType>, dstID, srcID, _1 ); + return std::bind( fieldCpySweepFunction<DstType,SrcType>, dstID, srcID, std::placeholders::_1 ); } diff --git a/src/domain_decomposition/BlockStorage.cpp b/src/domain_decomposition/BlockStorage.cpp index b5148482f5fd27c1a5cfe9d358ffadaf65b0bf6d..9ee33473a1b8100cf8f88d162093502812334fe6 100644 --- a/src/domain_decomposition/BlockStorage.cpp +++ b/src/domain_decomposition/BlockStorage.cpp @@ -46,7 +46,7 @@ namespace domain_decomposition { //********************************************************************************************************************** void BlockStorage::mapToPeriodicDomain( real_t & x, real_t & y, real_t & z ) const { - boost::array< bool, 3 > periodic; + std::array< bool, 3 > periodic; periodic[0] = periodic_[0]; periodic[1] = periodic_[1]; periodic[2] = periodic_[2]; @@ -62,7 +62,7 @@ void BlockStorage::mapToPeriodicDomain( real_t & x, real_t & y, real_t & z ) con //********************************************************************************************************************** bool BlockStorage::periodicIntersect( const math::AABB & box1, const math::AABB & box2 ) const { - boost::array< bool, 3 > periodic; + std::array< bool, 3 > periodic; periodic[0] = periodic_[0]; periodic[1] = periodic_[1]; periodic[2] = periodic_[2]; @@ -73,12 +73,12 @@ bool BlockStorage::periodicIntersect( const math::AABB & box1, const math::AABB //********************************************************************************************************************** /*! * For documentation, see documentation of free function -* 'bool periodicIntersect( const boost::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB & box1, const math::AABB & box2 )' +* 'bool periodicIntersect( const std::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB & box1, const math::AABB & box2 )' */ //********************************************************************************************************************** bool BlockStorage::periodicIntersect( const math::AABB & box1, const math::AABB & box2, const real_t dx ) const { - boost::array< bool, 3 > periodic; + std::array< bool, 3 > periodic; periodic[0] = periodic_[0]; periodic[1] = periodic_[1]; periodic[2] = periodic_[2]; diff --git a/src/domain_decomposition/MakeBlockDataInitFunction.h b/src/domain_decomposition/MakeBlockDataInitFunction.h index 466f944c110341acdde00a786e45fa39d3764e05..de41cd696de30b312f47883cbc59987a3e6b71d2 100644 --- a/src/domain_decomposition/MakeBlockDataInitFunction.h +++ b/src/domain_decomposition/MakeBlockDataInitFunction.h @@ -23,7 +23,6 @@ #include "IBlock.h" -#include <boost/bind.hpp> #include <functional> @@ -35,119 +34,19 @@ namespace domain_decomposition { /// \cond internal namespace internal { - template<class T> - T * newFunc( const IBlock* const ) { - return new T(); + template<class T, typename... Args> + T * newFunc( const IBlock* const, Args&... args ) { + return new T(args...); } - - template<class T, class P1> - T * newFunc( const IBlock* const , const P1 & p1 ) { - return new T(p1); - } - - template<class T, class P1, class P2> - T * newFunc( const IBlock* const , const P1 & p1, const P2 & p2 ) { - return new T(p1, p2); - } - - template<class T, class P1, class P2, class P3> - T * newFunc( const IBlock* const , const P1 & p1, const P2 & p2, const P3 & p3 ) { - return new T(p1, p2, p3); - } - - template<class T, class P1, class P2, class P3, class P4> - T * newFunc( const IBlock* const , const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4 ) { - return new T(p1, p2, p3, p4); - } - - template<class T, class P1, class P2, class P3, class P4, class P5> - T * newFunc( const IBlock* const , const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5 ) { - return new T(p1, p2, p3, p4, p5); - } - - template<class T, class P1, class P2, class P3, class P4, class P5, class P6> - T * newFunc( const IBlock* const , const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6 ) { - return new T(p1, p2, p3, p4, p5, p6); - } - - template<class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7> - T * newFunc( const IBlock* const , const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6, const P7 & p7 ) { - return new T(p1, p2, p3, p4, p5, p6,p7); - } - - template<class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8> - T * newFunc( const IBlock* const , const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6, const P7 & p7, const P8 & p8 ) { - return new T(p1, p2, p3, p4, p5, p6, p7,p8 ); - } - - template<class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9> - T * newFunc( const IBlock* const , const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6, const P7 & p7, const P8 & p8, const P9 & p9 ) { - return new T(p1, p2, p3, p4, p5, p6, p7,p8, p9 ); - } - } // namespace internal /// \endcond -template<class T> -std::function< T* ( const IBlock* const block ) > -makeBlockDataInitFunction() { - return boost::bind( internal::newFunc<T>, _1); -} - -template<class T, class P1> -std::function< T* ( const IBlock* const block ) > -makeBlockDataInitFunction(const P1 & p1) { - return boost::bind( internal::newFunc<T,P1>, _1,p1); -} - -template<class T, class P1, class P2> -std::function< T* ( const IBlock* const block ) > -makeBlockDataInitFunction(const P1 & p1, const P2 & p2) { - return boost::bind( internal::newFunc<T,P1,P2>, _1,p1,p2); -} - -template<class T, class P1, class P2, class P3> -std::function< T* ( const IBlock* const block ) > -makeBlockDataInitFunction(const P1 & p1, const P2 & p2, const P3 & p3) { - return boost::bind( internal::newFunc<T,P1,P2,P3>, _1,p1,p2,p3); -} - -template<class T, class P1, class P2, class P3, class P4> -std::function< T* ( const IBlock* const block ) > -makeBlockDataInitFunction(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4) { - return boost::bind( internal::newFunc<T,P1,P2,P3,P4>, _1,p1,p2,p3,p4); -} - -template<class T, class P1, class P2, class P3, class P4, class P5> -std::function< T* ( const IBlock* const block ) > -makeBlockDataInitFunction(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5) { - return boost::bind( internal::newFunc<T,P1,P2,P3,P4,P5>, _1,p1,p2,p3,p4,p5); -} - -template<class T, class P1, class P2, class P3, class P4, class P5, class P6> -std::function< T* ( const IBlock* const block ) > -makeBlockDataInitFunction(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6) { - return boost::bind( internal::newFunc<T,P1,P2,P3,P4,P5,P6>, _1,p1,p2,p3,p4,p5,p6); -} - -template<class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7> -std::function< T* ( const IBlock* const block ) > -makeBlockDataInitFunction(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6, const P7 & p7) { - return boost::bind( internal::newFunc<T,P1,P2,P3,P4,P5,P6,P7>, _1,p1,p2,p3,p4,p5,p6,p7); -} - -template<class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8> -std::function< T* ( const IBlock* const block ) > -makeBlockDataInitFunction(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6, const P7 & p7, const P8 & p8) { - return boost::bind( internal::newFunc<T,P1,P2,P3,P4,P5,P6,P7,P8>, _1,p1,p2,p3,p4,p5,p6,p7,p8); -} - -template<class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9> +template<class T, typename... Args> std::function< T* ( const IBlock* const block ) > -makeBlockDataInitFunction(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6, const P7 & p7, const P8 & p8, const P9 & p9) { - return boost::bind( internal::newFunc<T,P1,P2,P3,P4,P5,P6,P7,P8,P9>, _1,p1,p2,p3,p4,p5,p6,p7,p8,p9); +makeBlockDataInitFunction(Args&&... args) { + return std::bind( internal::newFunc<T,Args...>, std::placeholders::_1, std::forward<Args>(args)... ); } diff --git a/src/domain_decomposition/MapPointToPeriodicDomain.cpp b/src/domain_decomposition/MapPointToPeriodicDomain.cpp index d63c0ccd219665c5bf0e4c5ed2f6c0ca00b98e01..82f365e0e5d9bd733f7207eb407a7a7cadc57036 100644 --- a/src/domain_decomposition/MapPointToPeriodicDomain.cpp +++ b/src/domain_decomposition/MapPointToPeriodicDomain.cpp @@ -29,7 +29,7 @@ namespace domain_decomposition { -void mapPointToPeriodicDomain( const boost::array< bool, 3 > & periodic, const AABB & domain, real_t & x, real_t & y, real_t & z ) +void mapPointToPeriodicDomain( const std::array< bool, 3 > & periodic, const AABB & domain, real_t & x, real_t & y, real_t & z ) { if( periodic[0] ) { diff --git a/src/domain_decomposition/MapPointToPeriodicDomain.h b/src/domain_decomposition/MapPointToPeriodicDomain.h index 39c39c314048840724d22047daf325dd993c1fef..21107b075bd2f35785642cd41a6e169f8145cbd9 100644 --- a/src/domain_decomposition/MapPointToPeriodicDomain.h +++ b/src/domain_decomposition/MapPointToPeriodicDomain.h @@ -25,7 +25,7 @@ #include "core/math/AABB.h" #include "core/math/Vector3.h" -#include <boost/array.hpp> +#include <array> @@ -42,12 +42,12 @@ namespace domain_decomposition { * The min points of the domain are included in the simulation space, the max points are excluded! */ //********************************************************************************************************************** -void mapPointToPeriodicDomain( const boost::array< bool, 3 > & periodic, const AABB & domain, real_t & x, real_t & y, real_t & z ); +void mapPointToPeriodicDomain( const std::array< bool, 3 > & periodic, const AABB & domain, real_t & x, real_t & y, real_t & z ); /// see documetation of 'void mapPointToPeriodicDomain( const boost::array< bool, 3 > & periodic, const AABB & domain, real_t & x, real_t & y, real_t & z )' -inline void mapPointToPeriodicDomain( const boost::array< bool, 3 > & periodic, const AABB & domain, Vector3< real_t > & p ) +inline void mapPointToPeriodicDomain( const std::array< bool, 3 > & periodic, const AABB & domain, Vector3< real_t > & p ) { mapPointToPeriodicDomain( periodic, domain, p[0], p[1], p[2] ); } @@ -55,7 +55,7 @@ inline void mapPointToPeriodicDomain( const boost::array< bool, 3 > & periodic, /// see documetation of 'void mapPointToPeriodicDomain( const boost::array< bool, 3 > & periodic, const AABB & domain, real_t & x, real_t & y, real_t & z )' -inline Vector3< real_t > mapPointToPeriodicDomain( const boost::array< bool, 3 > & periodic, const AABB & domain, const Vector3< real_t > & p ) +inline Vector3< real_t > mapPointToPeriodicDomain( const std::array< bool, 3 > & periodic, const AABB & domain, const Vector3< real_t > & p ) { Vector3< real_t > point( p ); mapPointToPeriodicDomain( periodic, domain, point[0], point[1], point[2] ); diff --git a/src/domain_decomposition/PeriodicIntersect.cpp b/src/domain_decomposition/PeriodicIntersect.cpp new file mode 100644 index 0000000000000000000000000000000000000000..355e666c834a1fd7d13cb6d8364dd130cadbccea --- /dev/null +++ b/src/domain_decomposition/PeriodicIntersect.cpp @@ -0,0 +1,102 @@ +//====================================================================================================================== +// +// This file is part of waLBerla. waLBerla is free software: you can +// redistribute it and/or modify it under the terms of the GNU General Public +// License as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// waLBerla is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. +// +//! \file PeriodicIntersect.cpp +//! \author Sebastian Eibl <sebastian.eibl@fau.de> +// +//====================================================================================================================== + +#include "PeriodicIntersect.h" +#include "MapPointToPeriodicDomain.h" + +namespace walberla { +namespace domain_decomposition { + +bool periodicIntersect( const std::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB & box1, const math::AABB & box2 ) +{ + auto min1 = box1.minCorner(); + auto min2 = box2.minCorner(); + auto max1 = box1.maxCorner(); + auto max2 = box2.maxCorner(); + + mapPointToPeriodicDomain(periodic, domain, min1); + mapPointToPeriodicDomain(periodic, domain, min2); + mapPointToPeriodicDomain(periodic, domain, max1); + mapPointToPeriodicDomain(periodic, domain, max2); + + bool flag = false; + + if (max1[0] > max2[0]) + { + if ( (max1[0]-max2[0]) < box1.xSize() ) flag = true; + } else + { + if ( (max2[0]-max1[0]) < box2.xSize() ) flag = true; + } + if (min1[0] > min2[0]) + { + if ( (min1[0]-min2[0]) < box2.xSize() ) flag = true; + } else + { + if ( (min2[0]-min1[0]) < box1.xSize() ) flag = true; + } + + if (!flag) return false; + flag = false; + + if (max1[1] > max2[1]) + { + if ( (max1[1]-max2[1]) < box1.ySize() ) flag = true; + } else + { + if ( (max2[1]-max1[1]) < box2.ySize() ) flag = true; + } + if (min1[1] > min2[1]) + { + if ( (min1[1]-min2[1]) < box2.ySize() ) flag = true; + } else + { + if ( (min2[1]-min1[1]) < box1.ySize() ) flag = true; + } + + if (!flag) return false; + flag = false; + + if (max1[2] > max2[2]) + { + if ( (max1[2]-max2[2]) < box1.zSize() ) flag = true; + } else + { + if ( (max2[2]-max1[2]) < box2.zSize() ) flag = true; + } + if (min1[2] > min2[2]) + { + if ( (min1[2]-min2[2]) < box2.zSize() ) flag = true; + } else + { + if ( (min2[2]-min1[2]) < box1.zSize() ) flag = true; + } + + return flag; +} + +bool periodicIntersect( const std::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB& box1, const math::AABB & box2, const real_t dx ) +{ + return periodicIntersect(periodic, domain, box1.getExtended( dx ), box2); +} + + +} // namespace domain_decomposition +} // namespace walberla diff --git a/src/domain_decomposition/PeriodicIntersect.h b/src/domain_decomposition/PeriodicIntersect.h index 6fc0680d2fa21a5b5f3f41621bce133852609490..4ef824d991aea406fb6ca76e97217cecd198233c 100644 --- a/src/domain_decomposition/PeriodicIntersect.h +++ b/src/domain_decomposition/PeriodicIntersect.h @@ -14,97 +14,23 @@ // with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. // //! \file PeriodicIntersect.h -//! \ingroup domain_decomposition //! \author Sebastian Eibl <sebastian.eibl@fau.de> // //====================================================================================================================== #pragma once -#include "MapPointToPeriodicDomain.h" - #include "core/DataTypes.h" #include "core/math/AABB.h" #include "core/math/Vector3.h" -#include <boost/array.hpp> +#include <array> namespace walberla { namespace domain_decomposition { -bool periodicIntersect( const boost::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB & box1, const math::AABB & box2 ) -{ - auto min1 = box1.minCorner(); - auto min2 = box2.minCorner(); - auto max1 = box1.maxCorner(); - auto max2 = box2.maxCorner(); - - mapPointToPeriodicDomain(periodic, domain, min1); - mapPointToPeriodicDomain(periodic, domain, min2); - mapPointToPeriodicDomain(periodic, domain, max1); - mapPointToPeriodicDomain(periodic, domain, max2); - - bool flag = false; - - if (max1[0] > max2[0]) - { - if ( (max1[0]-max2[0]) < box1.xSize() ) flag = true; - } else - { - if ( (max2[0]-max1[0]) < box2.xSize() ) flag = true; - } - if (min1[0] > min2[0]) - { - if ( (min1[0]-min2[0]) < box2.xSize() ) flag = true; - } else - { - if ( (min2[0]-min1[0]) < box1.xSize() ) flag = true; - } - - if (!flag) return false; - flag = false; - - if (max1[1] > max2[1]) - { - if ( (max1[1]-max2[1]) < box1.ySize() ) flag = true; - } else - { - if ( (max2[1]-max1[1]) < box2.ySize() ) flag = true; - } - if (min1[1] > min2[1]) - { - if ( (min1[1]-min2[1]) < box2.ySize() ) flag = true; - } else - { - if ( (min2[1]-min1[1]) < box1.ySize() ) flag = true; - } - - if (!flag) return false; - flag = false; - - if (max1[2] > max2[2]) - { - if ( (max1[2]-max2[2]) < box1.zSize() ) flag = true; - } else - { - if ( (max2[2]-max1[2]) < box2.zSize() ) flag = true; - } - if (min1[2] > min2[2]) - { - if ( (min1[2]-min2[2]) < box2.zSize() ) flag = true; - } else - { - if ( (min2[2]-min1[2]) < box1.zSize() ) flag = true; - } - - return flag; -} - -bool periodicIntersect( const boost::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB& box1, const math::AABB & box2, const real_t dx ) -{ - return periodicIntersect(periodic, domain, box1.getExtended( dx ), box2); -} - +bool periodicIntersect( const std::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB & box1, const math::AABB & box2 ); +bool periodicIntersect( const std::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB& box1, const math::AABB & box2, const real_t dx ); } // namespace domain_decomposition } // namespace walberla diff --git a/src/domain_decomposition/PeriodicIntersectionVolume.cpp b/src/domain_decomposition/PeriodicIntersectionVolume.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ac61fc474155c852de64162e52f05b391eead46d --- /dev/null +++ b/src/domain_decomposition/PeriodicIntersectionVolume.cpp @@ -0,0 +1,53 @@ +//====================================================================================================================== +// +// This file is part of waLBerla. waLBerla is free software: you can +// redistribute it and/or modify it under the terms of the GNU General Public +// License as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// waLBerla is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. +// +//! \file PeriodicIntersectionVolume.cpp +//! \author Sebastian Eibl <sebastian.eibl@fau.de> +// +//====================================================================================================================== + +#include "core/logging/Logging.h" +#include "MapPointToPeriodicDomain.h" + +namespace walberla { +namespace domain_decomposition { + +real_t periodicIntersectionVolume( const std::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB & box1, const math::AABB & box2 ) +{ + const auto diagonal = (domain.maxCorner() - domain.minCorner()); + const auto halfDiagonal = real_t(0.5) * diagonal; + const auto center1 = box1.center(); + auto center2 = box2.center(); + + for (size_t dim = 0; dim < 3; ++dim) + { + if (periodic[dim]) + { + while ((center2[dim]-center1[dim])>halfDiagonal[dim]) center2[dim] -= diagonal[dim]; + while ((center2[dim]-center1[dim])<-halfDiagonal[dim]) center2[dim] += diagonal[dim]; + } + } + + return box1.intersectionVolume(box2.getTranslated(center2 - box2.center())); +} + +real_t periodicIntersectionVolume( const std::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB& box1, const math::AABB & box2, const real_t dx ) +{ + return periodicIntersectionVolume(periodic, domain, box1.getExtended( dx ), box2); +} + + +} // namespace domain_decomposition +} // namespace walberla diff --git a/src/domain_decomposition/PeriodicIntersectionVolume.h b/src/domain_decomposition/PeriodicIntersectionVolume.h new file mode 100644 index 0000000000000000000000000000000000000000..15c13d70235e542e10f96b176c1e60c88c3e2c95 --- /dev/null +++ b/src/domain_decomposition/PeriodicIntersectionVolume.h @@ -0,0 +1,36 @@ +//====================================================================================================================== +// +// This file is part of waLBerla. waLBerla is free software: you can +// redistribute it and/or modify it under the terms of the GNU General Public +// License as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// waLBerla is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. +// +//! \file PeriodicIntersectionVolume.h +//! \author Sebastian Eibl <sebastian.eibl@fau.de> +// +//====================================================================================================================== + +#pragma once + +#include "core/DataTypes.h" +#include "core/math/AABB.h" +#include "core/math/Vector3.h" + +#include <array> + +namespace walberla { +namespace domain_decomposition { + +real_t periodicIntersectionVolume( const std::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB & box1, const math::AABB & box2 ); +real_t periodicIntersectionVolume( const std::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB& box1, const math::AABB & box2, const real_t dx ); + +} // namespace domain_decomposition +} // namespace walberla diff --git a/src/domain_decomposition/StructuredBlockStorage.h b/src/domain_decomposition/StructuredBlockStorage.h index 4315429d285f3189e82d367f75d0a2f48bd895c8..2d398ca3dcf3e363d1afae8b76efbcb449c7c6c1 100644 --- a/src/domain_decomposition/StructuredBlockStorage.h +++ b/src/domain_decomposition/StructuredBlockStorage.h @@ -29,7 +29,7 @@ #include "core/cell/CellInterval.h" #include "core/debug/Debug.h" -#include <boost/bind.hpp> +#include <functional> namespace walberla { @@ -112,7 +112,7 @@ public: bdc.incompatibleSelectors_, bdc.identifier_ ); return *this; } template< typename T > StructuredBlockDataAdder & operator<<( const StructuredBlockDataCreator<T> & sbdc ) { - dataHandling_.add( walberla::make_shared< internal::BlockDataHandlingHelper<T> >( walberla::make_shared< internal::BlockDataHandlingFunctionAdaptor<T> >( boost::bind( sbdc.function_, _1, &storage_ ) ) ), + dataHandling_.add( walberla::make_shared< internal::BlockDataHandlingHelper<T> >( walberla::make_shared< internal::BlockDataHandlingFunctionAdaptor<T> >( std::bind( sbdc.function_, std::placeholders::_1, &storage_ ) ) ), sbdc.requiredSelectors_, sbdc.incompatibleSelectors_, sbdc.identifier_ ); return *this; } operator BlockDataID() { return storage_.getBlockStorage().addBlockData( dataHandling_, identifier_ ); } private: @@ -1076,7 +1076,7 @@ inline BlockDataID StructuredBlockStorage::addStructuredBlockData( const std::string& identifier, const Set<SUID>& requiredSelectors, const Set<SUID>& incompatibleSelectors ) { internal::SelectableBlockDataHandlingWrapper dataHandling( - walberla::make_shared< internal::BlockDataHandlingHelper<T> >( walberla::make_shared< internal::BlockDataHandlingFunctionAdaptor<T> >( boost::bind( function, _1, this ) ) ), + walberla::make_shared< internal::BlockDataHandlingHelper<T> >( walberla::make_shared< internal::BlockDataHandlingFunctionAdaptor<T> >( std::bind( function, std::placeholders::_1, this ) ) ), requiredSelectors, incompatibleSelectors, identifier ); diff --git a/src/field/StabilityChecker.h b/src/field/StabilityChecker.h index 396a7c07725f3ec835389fa370bd92fabdd1d02e..74b4470ed093b8dbd6ab7d1fdb2d74a182bb79be 100644 --- a/src/field/StabilityChecker.h +++ b/src/field/StabilityChecker.h @@ -394,7 +394,7 @@ void StabilityChecker< Field_T, Filter_T >::operator()() vtkWriter->addCellDataWriter( walberla::make_shared< vtk::DumpBlockStructureProcess >( "process" ) ); vtkWriter->addCellDataWriter( walberla::make_shared< vtk::DumpBlockStructureLevel >( "level" ) ); - vtkWriter->addCellDataWriter( walberla::make_shared< FValueVTKWriter >( boost::ref( failedCells_ ), "F" ) ); + vtkWriter->addCellDataWriter( walberla::make_shared< FValueVTKWriter >( std::ref( failedCells_ ), "F" ) ); vtkWriter->addCellDataWriter( walberla::make_shared< LocalCoordVTKWriter >( "blockLocalCoordinate" ) ); vtkWriter->addCellDataWriter( walberla::make_shared< GlobalCoordVTKWriter >( "globalCoordinate" ) ); diff --git a/src/field/adaptors/AdaptorCreators.h b/src/field/adaptors/AdaptorCreators.h index af7f5e55bd0e4756f67820945b61eb2d31002bea..1c410ca91246600c385f5ba0a6691b7a67474462 100644 --- a/src/field/adaptors/AdaptorCreators.h +++ b/src/field/adaptors/AdaptorCreators.h @@ -23,7 +23,9 @@ #pragma once #include "blockforest/BlockDataHandling.h" -#include <boost/bind.hpp> + +#include <functional> + namespace walberla { diff --git a/src/field/allocation/FieldAllocator.h b/src/field/allocation/FieldAllocator.h index 5be0ecf4b0dbd2b5e292d446dd13d62aae9aca23..4ab58c0fe1d82195f28a64627d4577fdd9db3336 100644 --- a/src/field/allocation/FieldAllocator.h +++ b/src/field/allocation/FieldAllocator.h @@ -48,6 +48,8 @@ namespace field { { public: + virtual ~FieldAllocator() = default; + /** * \brief Allocate memory for a field of given sizes and initializes reference counter with one * diff --git a/src/field/interpolators/NearestNeighborFieldInterpolator.h b/src/field/interpolators/NearestNeighborFieldInterpolator.h index 45e9110de725173af89a4aed20e1d6290b5278a5..975c55edb4c52d0ea197391a88b271588bbf7729 100644 --- a/src/field/interpolators/NearestNeighborFieldInterpolator.h +++ b/src/field/interpolators/NearestNeighborFieldInterpolator.h @@ -121,7 +121,7 @@ public: *interpolationResultBegin = baseField_(curCell, f); ++interpolationResultBegin; } - break; + return; } } } diff --git a/src/field/iterators/IteratorMacros.h b/src/field/iterators/IteratorMacros.h index 0c11a6014fc6447147574857fcceb3a47cc1cb65..162028971bee80e5c5dc3e1408926154050883f7 100644 --- a/src/field/iterators/IteratorMacros.h +++ b/src/field/iterators/IteratorMacros.h @@ -486,7 +486,7 @@ CODE \ ++it0; ++it1; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ } \ } \ else \ @@ -503,7 +503,7 @@ CODE \ ++it0; ++it1; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ } \ } } @@ -532,8 +532,8 @@ CODE \ ++it0; ++it1; ++it2; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ } \ } \ else \ @@ -551,11 +551,11 @@ CODE \ ++it0; ++it1; ++it2; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ } \ } } - + // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead #define WALBERLA_FOR_ALL_CELLS_OMP_10( it0, f0, it1, f1, it2, f2, it3, f3, omp, CODE ) \ { WALBERLA_ASSERT_NOT_NULLPTR_1( (f0) ); \ @@ -584,9 +584,9 @@ CODE \ ++it0; ++it1; ++it2; ++it3; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ } \ } \ else \ @@ -605,9 +605,9 @@ CODE \ ++it0; ++it1; ++it2; ++it3; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ } \ } } @@ -642,10 +642,10 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \ } \ } \ else \ @@ -665,10 +665,10 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \ } \ } } @@ -706,11 +706,11 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); \ - WALBERLA_ASSERT( it5 == (f5)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \ } \ } \ else \ @@ -731,11 +731,11 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); \ - WALBERLA_ASSERT( it5 == (f5)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \ } \ } } @@ -776,12 +776,12 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); \ - WALBERLA_ASSERT( it5 == (f5)->end() ); \ - WALBERLA_ASSERT( it6 == (f6)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); \ } \ } \ else \ @@ -803,12 +803,12 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); \ - WALBERLA_ASSERT( it5 == (f5)->end() ); \ - WALBERLA_ASSERT( it6 == (f6)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); \ } \ } } @@ -852,13 +852,13 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6; ++it7; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); \ - WALBERLA_ASSERT( it5 == (f5)->end() ); \ - WALBERLA_ASSERT( it6 == (f6)->end() ); \ - WALBERLA_ASSERT( it7 == (f7)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it7, (f7)->end() ); \ } \ } \ else \ @@ -881,16 +881,16 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6; ++it7; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); \ - WALBERLA_ASSERT( it5 == (f5)->end() ); \ - WALBERLA_ASSERT( it6 == (f6)->end() ); \ - WALBERLA_ASSERT( it7 == (f7)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it7, (f7)->end() ); \ } \ } } - + #else // == not WALBERLA_CXX_COMPILER_IS_MSVC #define WALBERLA_FOR_ALL_CELLS_XYZ_OMP( field, omp, CODE ) \ @@ -956,7 +956,7 @@ } \ } \ } } - + // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_XYZ_OMP' (using the same signature) instead #define WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_XYZ_OMP_4( field, gl, omp, CODE ) \ { WALBERLA_ASSERT_NOT_NULLPTR_1( (field) ); \ @@ -1041,7 +1041,7 @@ } \ } \ } } - + #define WALBERLA_FOR_ALL_CELLS_YZ_OMP( field, omp, CODE ) \ { WALBERLA_ASSERT_NOT_NULLPTR_1( (field) ); \ const ::walberla::cell_idx_t ySize__ = ::walberla::cell_idx_c( (field)->ySize() ); \ @@ -1096,7 +1096,7 @@ } \ } \ } } - + // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_YZ_OMP' (using the same signature) instead #define WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_YZ_OMP_4( field, gl, omp, CODE ) \ { WALBERLA_ASSERT_NOT_NULLPTR_1( (field) ); \ @@ -1168,7 +1168,7 @@ } \ } \ } } - + // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead #define WALBERLA_FOR_ALL_CELLS_OMP_4( it0, f0, omp, CODE ) \ { WALBERLA_ASSERT_NOT_NULLPTR_1( (f0) ); \ @@ -1228,7 +1228,7 @@ CODE \ ++it0; ++it1; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ } \ } \ else \ @@ -1245,10 +1245,10 @@ CODE \ ++it0; ++it1; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ } \ } } - + // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead #define WALBERLA_FOR_ALL_CELLS_OMP_8( it0, f0, it1, f1, it2, f2, omp, CODE ) \ { WALBERLA_ASSERT_NOT_NULLPTR_1( (f0) ); \ @@ -1274,8 +1274,8 @@ CODE \ ++it0; ++it1; ++it2; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ } \ } \ else \ @@ -1293,11 +1293,11 @@ CODE \ ++it0; ++it1; ++it2; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ } \ } } - + // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead #define WALBERLA_FOR_ALL_CELLS_OMP_10( it0, f0, it1, f1, it2, f2, it3, f3, omp, CODE ) \ { WALBERLA_ASSERT_NOT_NULLPTR_1( (f0) ); \ @@ -1326,9 +1326,9 @@ CODE \ ++it0; ++it1; ++it2; ++it3; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ } \ } \ else \ @@ -1347,9 +1347,9 @@ CODE \ ++it0; ++it1; ++it2; ++it3; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ } \ } } @@ -1384,10 +1384,10 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \ } \ } \ else \ @@ -1407,10 +1407,10 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \ } \ } } @@ -1448,11 +1448,11 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); \ - WALBERLA_ASSERT( it5 == (f5)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \ } \ } \ else \ @@ -1473,11 +1473,11 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); \ - WALBERLA_ASSERT( it5 == (f5)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \ } \ } } @@ -1518,12 +1518,12 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); \ - WALBERLA_ASSERT( it5 == (f5)->end() ); \ - WALBERLA_ASSERT( it6 == (f6)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); \ } \ } \ else \ @@ -1545,12 +1545,12 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); \ - WALBERLA_ASSERT( it5 == (f5)->end() ); \ - WALBERLA_ASSERT( it6 == (f6)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); \ } \ } } @@ -1594,13 +1594,13 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6; ++it7; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); \ - WALBERLA_ASSERT( it5 == (f5)->end() ); \ - WALBERLA_ASSERT( it6 == (f6)->end() ); \ - WALBERLA_ASSERT( it7 == (f7)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it7, (f7)->end() ); \ } \ } \ else \ @@ -1623,13 +1623,13 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6; ++it7; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); \ - WALBERLA_ASSERT( it5 == (f5)->end() ); \ - WALBERLA_ASSERT( it6 == (f6)->end() ); \ - WALBERLA_ASSERT( it7 == (f7)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it7, (f7)->end() ); \ } \ } } @@ -1650,7 +1650,7 @@ } \ } \ } } - + #define WALBERLA_FOR_ALL_CELLS_IN_INTERVAL_XYZ_OMP( interval, omp, CODE ) \ { for( ::walberla::cell_idx_t z = interval.zMin(); z <= interval.zMax(); ++z ) { \ for( ::walberla::cell_idx_t y = interval.yMin(); y <= interval.yMax(); ++y ) { \ @@ -1688,7 +1688,7 @@ CODE \ } \ } } - + #define WALBERLA_FOR_ALL_CELLS_IN_INTERVAL_YZ_OMP( interval, omp, CODE ) \ { for( ::walberla::cell_idx_t z = interval.zMin(); z <= interval.zMax(); ++z ) { \ for( ::walberla::cell_idx_t y = interval.yMin(); y <= interval.yMax(); ++y ) \ @@ -1697,7 +1697,7 @@ } \ } } -// Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_YZ_OMP' (using the same signature) instead +// Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_YZ_OMP' (using the same signature) instead #define WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_YZ_OMP_4( field, gl, omp, CODE ) \ { WALBERLA_ASSERT_NOT_NULLPTR_1( (field) ); \ WALBERLA_ASSERT_GREATER_EQUAL_2( (field)->nrOfGhostLayers(), gl ); \ @@ -1710,7 +1710,7 @@ CODE \ } \ } } - + // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead #define WALBERLA_FOR_ALL_CELLS_OMP_4( it0, f0, omp, CODE ) \ { WALBERLA_ASSERT_NOT_NULLPTR_1( (f0) ); \ @@ -1733,8 +1733,8 @@ CODE \ ++it0; ++it1; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); } - + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); } + // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead #define WALBERLA_FOR_ALL_CELLS_OMP_8( it0, f0, it1, f1, it2, f2, omp, CODE ) \ { WALBERLA_ASSERT_NOT_NULLPTR_1( (f0) ); \ @@ -1750,9 +1750,9 @@ CODE \ ++it0; ++it1; ++it2; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); } - + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); } + // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead #define WALBERLA_FOR_ALL_CELLS_OMP_10( it0, f0, it1, f1, it2, f2, it3, f3, omp, CODE ) \ { WALBERLA_ASSERT_NOT_NULLPTR_1( (f0) ); \ @@ -1771,10 +1771,10 @@ CODE \ ++it0; ++it1; ++it2; ++it3; \ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); } - + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); } + // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead #define WALBERLA_FOR_ALL_CELLS_OMP_12( it0, f0, it1, f1, it2, f2, it3, f3, it4, f4, omp, CODE ) \ { WALBERLA_ASSERT_NOT_NULLPTR_1( (f0) ); \ @@ -1796,10 +1796,10 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4;\ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); } + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); } // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead #define WALBERLA_FOR_ALL_CELLS_OMP_14( it0, f0, it1, f1, it2, f2, it3, f3, it4, f4, it5, f5, omp, CODE ) \ @@ -1825,11 +1825,11 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4; ++it5;\ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); \ - WALBERLA_ASSERT( it5 == (f5)->end() ); } + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); } // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead #define WALBERLA_FOR_ALL_CELLS_OMP_16( it0, f0, it1, f1, it2, f2, it3, f3, it4, f4, it5, f5, it6, f6, omp, CODE ) \ @@ -1858,12 +1858,12 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6;\ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); \ - WALBERLA_ASSERT( it5 == (f5)->end() ); \ - WALBERLA_ASSERT( it6 == (f6)->end() ); } + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); } // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead #define WALBERLA_FOR_ALL_CELLS_OMP_18( it0, f0, it1, f1, it2, f2, it3, f3, it4, f4, it5, f5, it6, f6, it7, f7, omp, CODE ) \ @@ -1895,13 +1895,13 @@ CODE \ ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6; ++it7;\ } \ - WALBERLA_ASSERT( it1 == (f1)->end() ); \ - WALBERLA_ASSERT( it2 == (f2)->end() ); \ - WALBERLA_ASSERT( it3 == (f3)->end() ); \ - WALBERLA_ASSERT( it4 == (f4)->end() ); \ - WALBERLA_ASSERT( it5 == (f5)->end() ); \ - WALBERLA_ASSERT( it6 == (f6)->end() ); \ - WALBERLA_ASSERT( it7 == (f7)->end() ); } + WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); \ + WALBERLA_ASSERT_EQUAL_2( it7, (f7)->end() ); } #endif // OpenMP diff --git a/src/field/python/FieldExport.impl.h b/src/field/python/FieldExport.impl.h index ecbbbae8ca9d72cd0b9c1db0352159297853a5c7..4dc9d0c3b0444561945dcfca2f1ed64fa5566bbd 100644 --- a/src/field/python/FieldExport.impl.h +++ b/src/field/python/FieldExport.impl.h @@ -1006,7 +1006,7 @@ namespace internal { auto result = make_shared<boost::python::object>(); AddToStorageExporter exporter( blocks, name, fs, gl, layout, type, initValue ); - python_coupling::for_each_noncopyable_type< FieldTypes > ( boost::ref(exporter) ); + python_coupling::for_each_noncopyable_type< FieldTypes > ( std::ref(exporter) ); if ( ! exporter.successful() ) { PyErr_SetString( PyExc_ValueError, "Adding Field failed."); @@ -1079,7 +1079,7 @@ namespace internal { auto fieldID = python_coupling::blockDataIDFromString( *blocks, name ); CreateVTKWriterExporter exporter(blocks, fieldID, vtkName); - python_coupling::for_each_noncopyable_type< FieldTypes > ( boost::ref(exporter) ); + python_coupling::for_each_noncopyable_type< FieldTypes > ( std::ref(exporter) ); if ( ! exporter.getCreatedWriter() ) { PyErr_SetString( PyExc_ValueError, "Failed to create writer"); throw boost::python::error_already_set(); @@ -1154,7 +1154,7 @@ namespace internal { auto fieldID = python_coupling::blockDataIDFromString( *blocks, name ); CreateFlagFieldVTKWriterExporter exporter(blocks, fieldID, vtkName, flagMapping); - python_coupling::for_each_noncopyable_type< FieldTypes > ( boost::ref(exporter) ); + python_coupling::for_each_noncopyable_type< FieldTypes > ( std::ref(exporter) ); if ( ! exporter.getCreatedWriter() ) { PyErr_SetString( PyExc_ValueError, "Failed to create writer"); throw boost::python::error_already_set(); @@ -1221,7 +1221,7 @@ namespace internal { auto fieldID = python_coupling::blockDataIDFromString( *blocks, name ); CreateBinarizationVTKWriterExporter exporter(blocks, fieldID, vtkName, mask); - python_coupling::for_each_noncopyable_type< FieldTypes > ( boost::ref(exporter) ); + python_coupling::for_each_noncopyable_type< FieldTypes > ( std::ref(exporter) ); if ( ! exporter.getCreatedWriter() ) { PyErr_SetString( PyExc_ValueError, "Failed to create writer"); throw boost::python::error_already_set(); diff --git a/src/gather/DataProcessor.h b/src/gather/DataProcessor.h index a2efd154aef4d02a762f15f7feaa903a17c30fe5..b337becc9a3aae5bb2c3782df4e9d37e09354d05 100644 --- a/src/gather/DataProcessor.h +++ b/src/gather/DataProcessor.h @@ -43,6 +43,8 @@ class DataProcessor { public: + virtual ~DataProcessor() = default; + /* * Process "graph like" data * every entry in the outer vector is a data-point. diff --git a/src/geometry/bodies/DynamicBody.h b/src/geometry/bodies/DynamicBody.h index dd666f106720f9a45aa01c55710323e1437106d7..a3c6ccca5a61981a381644bfd9e8e4b908b63097 100644 --- a/src/geometry/bodies/DynamicBody.h +++ b/src/geometry/bodies/DynamicBody.h @@ -30,6 +30,7 @@ namespace geometry { class AbstractBody { public: + virtual ~AbstractBody() = default; virtual bool contains (const Vector3<real_t> & point ) const = 0; virtual FastOverlapResult fastOverlapCheck ( const Vector3<real_t> & cellMidpoint, real_t dx ) const = 0; virtual FastOverlapResult fastOverlapCheck ( const AABB & box ) const = 0; diff --git a/src/geometry/initializer/BoundaryFromDomainBorder.impl.h b/src/geometry/initializer/BoundaryFromDomainBorder.impl.h index 9984fcaca34a6a4da0ca99d5e385d7b7469275da..dca93f84d01ce55b345fe585b1b34263856249f8 100644 --- a/src/geometry/initializer/BoundaryFromDomainBorder.impl.h +++ b/src/geometry/initializer/BoundaryFromDomainBorder.impl.h @@ -106,7 +106,7 @@ void BoundaryFromDomainBorder<Handling>::init( stencil::Direction direction, const cell_idx_t wd = wallDistance; - CellInterval dBB = blocks_.getDomainCellBB(); + CellInterval dBB = blocks_.getDomainCellBB( blocks_.getLevel(*blockIt) ); for( uint_t dim = 0; dim< 3; ++dim ) switch ( stencil::c[dim][direction] ) diff --git a/src/geometry/initializer/BoundarySetter.h b/src/geometry/initializer/BoundarySetter.h index 256ec58444530bcce20502a4541cab8b3a1b951c..b9fe341228dca130ada4f2f8647d98cfcc1f9b3d 100644 --- a/src/geometry/initializer/BoundarySetter.h +++ b/src/geometry/initializer/BoundarySetter.h @@ -194,7 +194,10 @@ namespace initializer { } if ( boundaryConfigBlock_ ) + { bcConfig_ = boundaryHandling_->createBoundaryConfiguration( boundaryUID_, boundaryConfigBlock_ ); + boundaryConfigBlock_ = Config::BlockHandle(); // discard the config block so we don't unnecessarily run createBoundaryConfiguration more than once with the same arguments + } flag_ = boundaryHandling_->getBoundaryMask( boundaryUID_ ); if ( ! field::isFlag( flag_ ) ) diff --git a/src/lbm/BlockForestEvaluation.h b/src/lbm/BlockForestEvaluation.h index 5a8ed59d7a9772dba7fbcf3a5ff65553ff50357c..f9b823696a8aa942545c73648de02bd03faa0d30 100644 --- a/src/lbm/BlockForestEvaluation.h +++ b/src/lbm/BlockForestEvaluation.h @@ -38,8 +38,8 @@ #include "field/CellCounter.h" #include "field/FlagUID.h" -#include <boost/bind.hpp> +#include <functional> #include <map> #include <string> #include <sstream> diff --git a/src/lbm/boundary/DynamicUBB.h b/src/lbm/boundary/DynamicUBB.h index 03f4af7c8fc980b210eff4576bf64f0a7d893010..67425aa05cc721a13cfe746e000520bbf6052fdd 100644 --- a/src/lbm/boundary/DynamicUBB.h +++ b/src/lbm/boundary/DynamicUBB.h @@ -78,13 +78,29 @@ public: origin_[0] = aabb.xMin() + real_c(0.5) * dx_[0]; origin_[1] = aabb.yMin() + real_c(0.5) * dx_[1]; origin_[2] = aabb.zMin() + real_c(0.5) * dx_[2]; + + if( !timeTracker_ ) + { + velocity_( time_ ); + } } + DynamicUBB( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField * const pdfField, + const uint_t level, const VelocityFunctor_T & velocity, const AABB & aabb ) : + DynamicUBB( boundaryUID, uid, pdfField, nullptr, level, velocity, aabb ) + {} shared_ptr< TimeTracker > getTimeTracker() { return timeTracker_; } void pushFlags( std::vector< FlagUID > & uids ) const { uids.push_back( uid_ ); } - void beforeBoundaryTreatment() { time_ = timeTracker_->getTime( level_ ); velocity_( time_ ); } + void beforeBoundaryTreatment() + { + if( timeTracker_ ) + { + time_ = timeTracker_->getTime( level_ ); + velocity_( time_ ); + } + } void afterBoundaryTreatment() const {} template< typename Buffer_T > @@ -113,7 +129,7 @@ public: WALBERLA_ASSERT_EQUAL( nz, z + cell_idx_c( stencil::cz[ dir ] ) ); WALBERLA_ASSERT_UNEQUAL( mask & this->mask_, numeric_cast<flag_t>(0) ); WALBERLA_ASSERT_EQUAL( mask & this->mask_, this->mask_ ); // only true if "this->mask_" only contains one single flag, which is the case for the - // current implementation of this boundary condition (SimpleUBB) + // current implementation of this boundary condition (DynamicUBB) const Vector3< real_t > pos( origin_[0] + real_c(nx) * dx_[0], origin_[1] + real_c(ny) * dx_[1], diff --git a/src/lbm/boundary/ParserUBB.h b/src/lbm/boundary/ParserUBB.h new file mode 100644 index 0000000000000000000000000000000000000000..82bfff5e2ba37d7366f1bf1318a1992e664a7602 --- /dev/null +++ b/src/lbm/boundary/ParserUBB.h @@ -0,0 +1,546 @@ +//====================================================================================================================== +// +// This file is part of waLBerla. waLBerla is free software: you can +// redistribute it and/or modify it under the terms of the GNU General Public +// License as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// waLBerla is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. +// +//! \file ParserUBB.h +//! \ingroup lbm +//! \author Michael Kuron <mkuron@icp.uni-stuttgart.de> +// +//====================================================================================================================== + +#pragma once + +#include "lbm/field/DensityAndVelocity.h" +#include "lbm/field/PdfField.h" +#include "lbm/refinement/TimeTracker.h" + +#include "boundary/Boundary.h" + +#include "core/DataTypes.h" +#include "core/cell/CellInterval.h" +#include "core/config/Config.h" +#include "core/debug/Debug.h" +#include "core/math/Vector3.h" +#include "core/math/ParserOMP.h" + +#include "field/FlagUID.h" + +#include "stencil/Directions.h" + +#include <vector> + + + +namespace walberla { +namespace lbm { + + + +template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce = false > +class ParserUBB : public Boundary<flag_t> +{ + typedef lbm::PdfField< LatticeModel_T > PDFField; + typedef typename LatticeModel_T::Stencil Stencil; + +public: + + static const bool threadsafe = true; + + class Parser : public BoundaryConfiguration + { + public: + inline Parser( const Config::BlockHandle & config ); + inline Parser( std::array< std::string, 3 > & equations ); + Vector3< real_t > operator()( const Vector3< real_t > & x, const real_t t ) const; + Vector3< real_t > operator()( const Vector3< real_t > & x ) const; + bool isTimeDependent() const { return timeDependent_; } + const std::array< std::string, 3 > & equations() const { return equations_; } + + private: + std::array< math::FunctionParserOMP, 3 > parsers_; + std::array< std::string, 3 > equations_; + bool timeDependent_; + }; // class Parser + + // constant velocity class is for API compatibility with UBB + class Velocity : public BoundaryConfiguration { + public: + Velocity( const Vector3< real_t > & _velocity ) : velocity_( _velocity ) {} + Velocity( const real_t _x, const real_t _y, const real_t _z ) : velocity_(_x,_y,_z) {} + inline Velocity( const Config::BlockHandle & config ); + + const Vector3< real_t > & velocity() const { return velocity_; } + + const real_t & x() const { return velocity_[0]; } + const real_t & y() const { return velocity_[1]; } + const real_t & z() const { return velocity_[2]; } + + Vector3< real_t > & velocity() { return velocity_; } + + real_t & x() { return velocity_[0]; } + real_t & y() { return velocity_[1]; } + real_t & z() { return velocity_[2]; } + + private: + Vector3< real_t > velocity_; + }; // class Velocity + + typedef GhostLayerField< shared_ptr<Parser>, 1 > ParserField; + typedef GhostLayerField< Vector3<real_t>, 1 > VelocityField; + + static shared_ptr<Parser> createConfiguration( const Config::BlockHandle & config ) + { return make_shared<Parser>( config ); } + + + + ParserUBB( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField * const pdfField, + FlagField<flag_t> * const flagField, const shared_ptr< TimeTracker > & timeTracker, + const uint_t level, const AABB & aabb ); + ParserUBB( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField * const pdfField, + FlagField<flag_t> * const flagField, const uint_t level, const AABB & aabb ); + + shared_ptr< TimeTracker > getTimeTracker() { return timeTracker_; } + + void pushFlags( std::vector< FlagUID > & uids ) const { uids.push_back( uid_ ); } + + void beforeBoundaryTreatment() + { + if( timeTracker_ ) + time_ = timeTracker_->getTime( level_ ); + } + void afterBoundaryTreatment() const {} + + template< typename Buffer_T > + inline void packCell( Buffer_T &, const cell_idx_t, const cell_idx_t, const cell_idx_t ) const; + + template< typename Buffer_T > + inline void registerCell( Buffer_T &, const flag_t, const cell_idx_t, const cell_idx_t, const cell_idx_t ); + + inline void registerCell( const flag_t, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z, const BoundaryConfiguration & parser ); + inline void registerCells( const flag_t, const CellInterval & cells, const BoundaryConfiguration & parser ); + template< typename CellIterator > + inline void registerCells( const flag_t, const CellIterator & begin, const CellIterator & end, const BoundaryConfiguration & parser ); + + inline void unregisterCell( const flag_t, const cell_idx_t, const cell_idx_t, const cell_idx_t ) const; + +#ifndef NDEBUG + inline void treatDirection( const cell_idx_t x, const cell_idx_t y, const cell_idx_t z, const stencil::Direction dir, + const cell_idx_t nx, const cell_idx_t ny, const cell_idx_t nz, const flag_t mask ); +#else + inline void treatDirection( const cell_idx_t x, const cell_idx_t y, const cell_idx_t z, const stencil::Direction dir, + const cell_idx_t nx, const cell_idx_t ny, const cell_idx_t nz, const flag_t /*mask*/ ); +#endif + + inline Vector3<real_t> getValue( const cell_idx_t x, cell_idx_t y, cell_idx_t z ) const; + inline Vector3<real_t> getValue( const cell_idx_t x, cell_idx_t y, cell_idx_t z, real_t t ) const; + +private: + + const FlagUID uid_; + + PDFField * const pdfField_; + + Vector3< real_t > origin_; + Vector3< real_t > dx_; + + // required to keep track of the simulation time + shared_ptr< TimeTracker > timeTracker_; // -> addPostBoundaryHandlingVoidFunction (when used with refinement time step) + real_t time_; + uint_t level_; + + shared_ptr<ParserField> parserField_; + shared_ptr<VelocityField> velocityField_; + +}; // class ParserUBB + +template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce> +inline ParserUBB<LatticeModel_T, flag_t, AdaptVelocityToExternalForce>::Parser::Parser( const Config::BlockHandle & config ) +: parsers_(), equations_(), timeDependent_( false ) +{ + if( !config ) + return; + + if( config.isDefined( "x" ) ) + { + equations_[0] = config.getParameter<std::string>( "x" ); + parsers_[0].parse( equations_[0] ); + if( parsers_[0].symbolExists( "t" ) ) + timeDependent_ = true; + } + if( config.isDefined( "y" ) ) + { + equations_[1] = config.getParameter<std::string>( "y" ); + parsers_[1].parse( equations_[1] ); + if( parsers_[1].symbolExists( "t" ) ) + timeDependent_ = true; + } + if( config.isDefined( "z" ) ) + { + equations_[2] = config.getParameter<std::string>( "z" ); + parsers_[2].parse( equations_[2] ); + if( parsers_[2].symbolExists( "t" ) ) + timeDependent_ = true; + } +} + +template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce> +inline ParserUBB<LatticeModel_T, flag_t, AdaptVelocityToExternalForce>::Parser::Parser( std::array< std::string, 3 > & equations ) +: parsers_(), equations_( equations ), timeDependent_( false ) +{ + if( equations_[0].length() > 0 ) + { + parsers_[0].parse( equations_[0] ); + if( parsers_[0].symbolExists( "t" ) ) + timeDependent_ = true; + } + if( equations_[1].length() > 0 ) + { + parsers_[1].parse( equations_[1] ); + if( parsers_[1].symbolExists( "t" ) ) + timeDependent_ = true; + } + if( equations_[2].length() > 0 ) + { + parsers_[2].parse( equations_[2] ); + if( parsers_[2].symbolExists( "t" ) ) + timeDependent_ = true; + } +} + +template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce > +inline ParserUBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce >::Velocity::Velocity( const Config::BlockHandle & config ) +{ + velocity_[0] = ( config && config.isDefined( "x" ) ) ? config.getParameter<real_t>( "x" ) : real_c(0.0); + velocity_[1] = ( config && config.isDefined( "y" ) ) ? config.getParameter<real_t>( "y" ) : real_c(0.0); + velocity_[2] = ( config && config.isDefined( "z" ) ) ? config.getParameter<real_t>( "z" ) : real_c(0.0); +} + +template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce> +Vector3< real_t > ParserUBB<LatticeModel_T, flag_t, AdaptVelocityToExternalForce>::Parser::operator()( const Vector3< real_t > & x, const real_t t ) const +{ + std::map< std::string, double > symbols; + symbols["x"] = x[0]; + symbols["y"] = x[1]; + symbols["z"] = x[2]; + symbols["t"] = t; + + Vector3< real_t > v; + v[0] = parsers_[0].evaluate( symbols ); + v[1] = parsers_[1].evaluate( symbols ); + v[2] = parsers_[2].evaluate( symbols ); + return v; +} + +template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce> +Vector3< real_t > ParserUBB<LatticeModel_T, flag_t, AdaptVelocityToExternalForce>::Parser::operator()( const Vector3< real_t > & x ) const +{ + WALBERLA_ASSERT( !timeDependent_ ); + + std::map< std::string, double > symbols; + symbols["x"] = x[0]; + symbols["y"] = x[1]; + symbols["z"] = x[2]; + + Vector3< real_t > v; + v[0] = parsers_[0].evaluate( symbols ); + v[1] = parsers_[1].evaluate( symbols ); + v[2] = parsers_[2].evaluate( symbols ); + return v; +} + + + +template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce> +inline ParserUBB<LatticeModel_T, flag_t, AdaptVelocityToExternalForce>::ParserUBB( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField * const pdfField, + FlagField<flag_t> * const flagField, const shared_ptr< TimeTracker > & timeTracker, + const uint_t level, const AABB & aabb ) + : Boundary<flag_t>( boundaryUID ), uid_( uid ), pdfField_( pdfField ), timeTracker_( timeTracker ), time_( real_t(0) ), level_( level ) +{ + WALBERLA_ASSERT_NOT_NULLPTR( pdfField_ ); + dx_[0] = aabb.xSize() / real_c( pdfField_->xSize() ); + dx_[1] = aabb.ySize() / real_c( pdfField_->ySize() ); + dx_[2] = aabb.zSize() / real_c( pdfField_->zSize() ); + origin_[0] = aabb.xMin() + real_c(0.5) * dx_[0]; + origin_[1] = aabb.yMin() + real_c(0.5) * dx_[1]; + origin_[2] = aabb.zMin() + real_c(0.5) * dx_[2]; + + if(flagField != NULL) + { + parserField_ = make_shared<ParserField> ( pdfField->xSize(), pdfField->ySize(), pdfField->zSize(), flagField->nrOfGhostLayers(), field::zyxf ); + velocityField_ = make_shared<VelocityField>( pdfField->xSize(), pdfField->ySize(), pdfField->zSize(), flagField->nrOfGhostLayers(), field::zyxf ); + } + else + { + parserField_ = make_shared<ParserField> ( pdfField->xSize(), pdfField->ySize(), pdfField->zSize(), pdfField->nrOfGhostLayers(), field::zyxf ); + velocityField_ = make_shared<VelocityField>( pdfField->xSize(), pdfField->ySize(), pdfField->zSize(), pdfField->nrOfGhostLayers(), field::zyxf ); + } +} + + + +template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce > +template< typename Buffer_T > +inline void ParserUBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce >::packCell( Buffer_T & buffer, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z ) const +{ + if( parserField_->get( x, y, z ) ) + { + auto & eqs = parserField_->get( x, y, z )->equations(); + buffer << true << eqs[0] << eqs[1] << eqs[2]; + } + else + { + buffer << false << velocityField_->get( x, y, z ); + } +} + + + +template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce > +template< typename Buffer_T > +inline void ParserUBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce >::registerCell( Buffer_T & buffer, const flag_t, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z ) +{ + bool isparser; + buffer >> isparser; + if( isparser ) + { + std::array< std::string, 3> eqs; + buffer >> eqs[0] >> eqs[1] >> eqs[2]; + + auto p = make_shared<Parser>(eqs); + parserField_->get( x, y, z ) = p; + } + else + { + buffer >> velocityField_->get( x, y, z ); + parserField_->get( x, y, z ) = nullptr; + } +} + + + +template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce> +inline ParserUBB<LatticeModel_T, flag_t, AdaptVelocityToExternalForce>::ParserUBB( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField * const pdfField, + FlagField<flag_t> * const flagField, const uint_t level, const AABB & aabb ) + : ParserUBB( boundaryUID, uid, pdfField, flagField, nullptr, level, aabb ) +{} + + + +template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce > +inline void ParserUBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce >::registerCell( const flag_t, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z, + const BoundaryConfiguration & parser ) +{ + WALBERLA_ASSERT_EQUAL( dynamic_cast< const Parser * >( &parser ), &parser ); + WALBERLA_ASSERT_NOT_NULLPTR( parserField_ ); + + if( auto v = dynamic_cast< const Velocity * >( &parser ) ) + { + velocityField_->get( x, y, z ) = v->velocity(); + parserField_->get( x, y, z ) = nullptr; + return; + } + + auto & p = dynamic_cast< const Parser & >( parser ); + + if( p.isTimeDependent() ) + { + parserField_->get( x, y, z ) = make_shared<Parser>(p); + } + else + { + const Vector3< real_t > pos( origin_[0] + real_c(x) * dx_[0], + origin_[1] + real_c(y) * dx_[1], + origin_[2] + real_c(z) * dx_[2] ); + velocityField_->get( x, y, z ) = p(pos); + parserField_->get( x, y, z ) = nullptr; + } +} + + + +template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce > +inline void ParserUBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce >::registerCells( const flag_t, const CellInterval & cells, const BoundaryConfiguration & parser ) +{ + WALBERLA_ASSERT_EQUAL( dynamic_cast< const Parser * >( &parser ), &parser ); + WALBERLA_ASSERT_NOT_NULLPTR( parserField_ ); + + if( auto v = dynamic_cast< const Velocity * >( &parser ) ) + { + for( auto cell = parserField_->beginSliceXYZ( cells ); cell != parserField_->end(); ++cell ) + { + velocityField_->get( cell.x(), cell.y(), cell.z() ) = v->velocity(); + *cell = nullptr; + } + return; + } + + auto & p = dynamic_cast< const Parser & >( parser ); + + if( p.isTimeDependent() ) + { + auto shared_p = make_shared<Parser>(p); + for( auto cell = parserField_->beginSliceXYZ( cells ); cell != parserField_->end(); ++cell ) + *cell = shared_p; + } + else + { + for( auto cell = parserField_->beginSliceXYZ( cells ); cell != parserField_->end(); ++cell ) + { + const Vector3< real_t > pos( origin_[0] + real_c(cell.x()) * dx_[0], + origin_[1] + real_c(cell.y()) * dx_[1], + origin_[2] + real_c(cell.z()) * dx_[2] ); + velocityField_->get( cell.x(), cell.y(), cell.z() ) = p(pos); + *cell = nullptr; + } + } +} + + + +template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce > +template< typename CellIterator > +inline void ParserUBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce >::registerCells( const flag_t, const CellIterator & begin, const CellIterator & end, + const BoundaryConfiguration & parser ) +{ + WALBERLA_ASSERT_EQUAL( dynamic_cast< const Parser * >( &parser ), &parser ); + WALBERLA_ASSERT_NOT_NULLPTR( parserField_ ); + + if( auto v = dynamic_cast< const Velocity * >( &parser ) ) + { + for( auto cell = begin; cell != end; ++cell ) + { + velocityField_->get( cell.x(), cell.y(), cell.z() ) = v->velocity(); + parserField_->get( cell->x(), cell->y(), cell->z() ) = nullptr; + } + return; + } + + auto & p = dynamic_cast< const Parser & >( parser ); + + if( p.isTimeDependent() ) + { + auto shared_p = make_shared<Parser>(p); + for( auto cell = begin; cell != end; ++cell ) + { + parserField_->get( cell->x(), cell->y(), cell->z() ) = shared_p; + } + } + else + { + for( auto cell = begin; cell != end; ++cell ) + { + const Vector3< real_t > pos( origin_[0] + real_c(cell->x()) * dx_[0], + origin_[1] + real_c(cell->y()) * dx_[1], + origin_[2] + real_c(cell->z()) * dx_[2] ); + velocityField_->get( cell->x(), cell->y(), cell->z() ) = p(pos); + parserField_->get( cell->x(), cell->y(), cell->z() ) = nullptr; + } + } +} + + + +template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce > +inline void ParserUBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce >::unregisterCell( const flag_t, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z ) const +{ + parserField_->get(x,y,z) = nullptr; +} + + + +template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce> +#ifndef NDEBUG +inline void ParserUBB<LatticeModel_T, flag_t, AdaptVelocityToExternalForce>::ParserUBB::treatDirection( const cell_idx_t x, const cell_idx_t y, const cell_idx_t z, const stencil::Direction dir, + const cell_idx_t nx, const cell_idx_t ny, const cell_idx_t nz, const flag_t mask ) +#else +inline void ParserUBB<LatticeModel_T, flag_t, AdaptVelocityToExternalForce>::ParserUBB::treatDirection( const cell_idx_t x, const cell_idx_t y, const cell_idx_t z, const stencil::Direction dir, + const cell_idx_t nx, const cell_idx_t ny, const cell_idx_t nz, const flag_t /*mask*/ ) +#endif + { + WALBERLA_ASSERT_EQUAL( nx, x + cell_idx_c( stencil::cx[ dir ] ) ); + WALBERLA_ASSERT_EQUAL( ny, y + cell_idx_c( stencil::cy[ dir ] ) ); + WALBERLA_ASSERT_EQUAL( nz, z + cell_idx_c( stencil::cz[ dir ] ) ); + WALBERLA_ASSERT_UNEQUAL( mask & this->mask_, numeric_cast<flag_t>(0) ); + WALBERLA_ASSERT_EQUAL( mask & this->mask_, this->mask_ ); // only true if "this->mask_" only contains one single flag, which is the case for the + // current implementation of this boundary condition (ParserUBB) + + Vector3<real_t> velocity; + if( parserField_->get(nx,ny,nz) ) + { + WALBERLA_ASSERT_NOT_NULLPTR( getTimeTracker(), "A TimeTracker is needed for time-dependent equations" ); + const Vector3< real_t > pos( origin_[0] + real_c(nx) * dx_[0], + origin_[1] + real_c(ny) * dx_[1], + origin_[2] + real_c(nz) * dx_[2] ); + velocity = (*parserField_->get(nx,ny,nz))( pos, time_ ); + } + else + { + velocity = velocityField_->get(nx,ny,nz); + } + + if( LatticeModel_T::compressible ) + { + const auto density = pdfField_->getDensity(x,y,z); + const auto vel = AdaptVelocityToExternalForce ? lbm::internal::AdaptVelocityToForce<LatticeModel_T>::get( x, y, z, pdfField_->latticeModel(), velocity, density ) : + velocity; + + pdfField_->get( nx, ny, nz, Stencil::invDirIdx(dir) ) = pdfField_->get( x, y, z, Stencil::idx[dir] ) - + ( real_c(6) * density * real_c(LatticeModel_T::w[ Stencil::idx[dir] ]) * + ( real_c(stencil::cx[ dir ]) * vel[0] + + real_c(stencil::cy[ dir ]) * vel[1] + + real_c(stencil::cz[ dir ]) * vel[2] ) ); + } + else + { + const auto vel = AdaptVelocityToExternalForce ? lbm::internal::AdaptVelocityToForce<LatticeModel_T>::get( x, y, z, pdfField_->latticeModel(), velocity, real_t(1) ) : + velocity; + + pdfField_->get( nx, ny, nz, Stencil::invDirIdx(dir) ) = pdfField_->get( x, y, z, Stencil::idx[dir] ) - + ( real_c(6) * real_c(LatticeModel_T::w[ Stencil::idx[dir] ]) * + ( real_c(stencil::cx[ dir ]) * vel[0] + + real_c(stencil::cy[ dir ]) * vel[1] + + real_c(stencil::cz[ dir ]) * vel[2] ) ); + } + } + + + +template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce > +inline Vector3<real_t> ParserUBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce >::getValue( const cell_idx_t x, cell_idx_t y, cell_idx_t z ) const +{ + return getValue( x, y, z, time_ ); +} + +template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce > +inline Vector3<real_t> ParserUBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce >::getValue( const cell_idx_t x, cell_idx_t y, cell_idx_t z, real_t t ) const +{ + Vector3<real_t> velocity; + if( parserField_->get(x,y,z) ) + { + WALBERLA_ASSERT_NOT_NULLPTR( getTimeTracker(), "A TimeTracker is needed for time-dependent equations" ); + const Vector3< real_t > pos( origin_[0] + real_c(x) * dx_[0], + origin_[1] + real_c(y) * dx_[1], + origin_[2] + real_c(z) * dx_[2] ); + velocity = (*parserField_->get(x,y,z))( pos, t ); + } + else + { + velocity = velocityField_->get(x,y,z); + } + return velocity; +} + + +} // namespace lbm +} // namespace walberla diff --git a/src/lbm/boundary/Pressure.h b/src/lbm/boundary/Pressure.h index a637b14d17133c33369a546163961a75e8f465a6..ae8afb05372001a7062c72df7e53a645e566e1b5 100644 --- a/src/lbm/boundary/Pressure.h +++ b/src/lbm/boundary/Pressure.h @@ -211,7 +211,7 @@ inline void Pressure< LatticeModel_T, flag_t >::treatDirection( const cell_idx_t WALBERLA_ASSERT_UNEQUAL( ( mask & this->mask_ ), numeric_cast<flag_t>(0) ); WALBERLA_ASSERT_EQUAL( ( mask & this->mask_ ), this->mask_ ); // only true if "this->mask_" only contains one single flag, which is the case for the - // current implementation of this boundary condition (SimplePressure) + // current implementation of this boundary condition (Pressure) Vector3<real_t> u = pdfField_->getVelocity(x,y,z); // result will be streamed to (x,y,z, stencil::inverseDir[d]) during sweep diff --git a/src/lbm/boundary/all.h b/src/lbm/boundary/all.h index 158a9f887948684e90d55437748ff481b52e22a7..31709c60e0e538dddaaf537fe0d661fb2b4833c1 100644 --- a/src/lbm/boundary/all.h +++ b/src/lbm/boundary/all.h @@ -31,6 +31,7 @@ #include "NoDiffusion.h" #include "NoSlip.h" #include "Outlet.h" +#include "ParserUBB.h" #include "Pressure.h" #include "SimpleDiffusionDirichlet.h" #include "SimplePAB.h" diff --git a/src/lbm/boundary/factories/DefaultBoundaryHandlingCollection.h b/src/lbm/boundary/factories/DefaultBoundaryHandlingCollection.h index e54c74bcabbc3f53b17579fa73142860243d0037..4bee0c6c165d99ce6c57d746ddef667106e8056f 100644 --- a/src/lbm/boundary/factories/DefaultBoundaryHandlingCollection.h +++ b/src/lbm/boundary/factories/DefaultBoundaryHandlingCollection.h @@ -26,6 +26,8 @@ #include "lbm/boundary/factories/DefaultBoundaryHandling.h" #include "lbm/boundary/factories/DefaultDiffusionBoundaryHandling.h" +#include <functional> + namespace walberla { namespace lbm{ @@ -67,7 +69,7 @@ public: static BlockDataID addDefaultBoundaryHandlingCollectionToStorage( const shared_ptr< StructuredBlockStorage >& bs, const std::string & identifier, const BlockDataID& flagFieldID, const BlockDataID& handlingID, const BlockDataID& diffusionHandlingID ) { - auto func = boost::bind( createDefaultBoundaryHandlingCollectionFactory, _1, _2, flagFieldID, handlingID, diffusionHandlingID ); + auto func = std::bind( createDefaultBoundaryHandlingCollectionFactory, std::placeholders::_1, std::placeholders::_2, flagFieldID, handlingID, diffusionHandlingID ); return bs->addStructuredBlockData< BoundaryHandlingCollection_T >( func, identifier ); } diff --git a/src/lbm/boundary/factories/DefaultDiffusionBoundaryHandling.h b/src/lbm/boundary/factories/DefaultDiffusionBoundaryHandling.h index 3104c3f7efda83d4cc2410729b6b0ea3b37a624a..42e3c7536baaf15361049affebc016eb46f7664d 100644 --- a/src/lbm/boundary/factories/DefaultDiffusionBoundaryHandling.h +++ b/src/lbm/boundary/factories/DefaultDiffusionBoundaryHandling.h @@ -36,6 +36,8 @@ #include <boost/tuple/tuple.hpp> +#include <functional> + namespace walberla { namespace lbm{ @@ -136,7 +138,7 @@ public: static BlockDataID addDefaultDiffusionBoundaryHandlingToStorage( const shared_ptr< StructuredBlockStorage >& bs, const std::string & identifier, const BlockDataID& flagFieldID, const Set<FlagUID>& domainFlagUIDs, const BlockDataID& pdfFieldID, const Set<FlagUID>& initFlagUIDs ) { - auto func = boost::bind( createDefaultDiffusionBoundaryHandlingFactory, _1, _2, flagFieldID, domainFlagUIDs, pdfFieldID, initFlagUIDs ); + auto func = std::bind( createDefaultDiffusionBoundaryHandlingFactory, std::placeholders::_1, std::placeholders::_2, flagFieldID, domainFlagUIDs, pdfFieldID, initFlagUIDs ); return bs->addStructuredBlockData< BoundaryHandling_T >( func, identifier ); } diff --git a/src/lbm/boundary/factories/ExtendedBoundaryHandlingFactory.h b/src/lbm/boundary/factories/ExtendedBoundaryHandlingFactory.h index b12fdc4bb5ed9046d01ca2733e7e9ba66503d1c6..11ae8af9d3ca08da723e218d37b90796a6e35e85 100644 --- a/src/lbm/boundary/factories/ExtendedBoundaryHandlingFactory.h +++ b/src/lbm/boundary/factories/ExtendedBoundaryHandlingFactory.h @@ -24,7 +24,7 @@ #include "lbm/boundary/FreeSlip.h" #include "lbm/boundary/NoSlip.h" #include "lbm/boundary/Pressure.h" -#include "lbm/boundary/UBB.h" +#include "lbm/boundary/ParserUBB.h" #include "lbm/boundary/Outlet.h" #include "lbm/boundary/Curved.h" @@ -82,7 +82,7 @@ public: typedef NoSlip< LatticeModel, flag_t > BcNoSlip; typedef FreeSlip< LatticeModel, FlagFieldT > BcFreeSlip; typedef Pressure< LatticeModel, flag_t > BcPressure; - typedef UBB<LatticeModel, flag_t> BcUBB; + typedef ParserUBB<LatticeModel, flag_t> BcUBB; typedef Outlet<LatticeModel, FlagFieldT > BcOutlet; typedef Curved<LatticeModel, FlagFieldT > BcCurved; @@ -144,7 +144,7 @@ ExtendedBoundaryHandlingFactory<LatticeModel, FlagFieldT>::ExtendedBoundaryHandl template <typename LatticeModel, typename FlagFieldT > typename ExtendedBoundaryHandlingFactory<LatticeModel, FlagFieldT>::BoundaryHandling * ExtendedBoundaryHandlingFactory<LatticeModel, FlagFieldT>::operator()( IBlock * const block, - const walberla::StructuredBlockStorage * const /*storage*/ ) const + const walberla::StructuredBlockStorage * const storage ) const { PdfFieldLM * const pdfField = block->getData< PdfFieldLM >( pdfField_ ); FlagFieldT * const flagField = block->getData< FlagFieldT >( flagField_ ); @@ -160,7 +160,7 @@ ExtendedBoundaryHandlingFactory<LatticeModel, FlagFieldT>::operator()( IBlock * BcNoSlip ( getNoSlipBoundaryUID(), getNoSlip(), pdfField ), BcFreeSlip ( getFreeSlipBoundaryUID(), getFreeSlip(), pdfField, flagField, mask ), BcPressure ( getPressureBoundaryUID(), getPressure(), pdfField ), - BcUBB ( getUBBBoundaryUID(), getUBB(), pdfField ), + BcUBB ( getUBBBoundaryUID(), getUBB(), pdfField, flagField, storage->getLevel(*block), block->getAABB() ), BcOutlet ( getOutletBoundaryUID(), getOutlet(), pdfField, flagField, mask ), BcCurved ( getCurvedBoundaryUID(), getCurved(), pdfField, flagField, mask ) ) diff --git a/src/lbm/python/ExportBasic.impl.h b/src/lbm/python/ExportBasic.impl.h index afae7a5a105fc0e4067d694eaa74e19b5817bb51..c0097f54eccce9d73217935797c41a37e9d3763e 100644 --- a/src/lbm/python/ExportBasic.impl.h +++ b/src/lbm/python/ExportBasic.impl.h @@ -165,7 +165,7 @@ namespace internal using namespace boost::python; LatticeModelCreator creator( compressible, equilibriumAccuracyOrder, stencil, collisionModel, forceModel ); - python_coupling::for_each_noncopyable_type<LatticeModels>( boost::ref(creator) ); + python_coupling::for_each_noncopyable_type<LatticeModels>( std::ref(creator) ); if ( creator.getResult() == object() ) { @@ -346,7 +346,7 @@ namespace internal internal::AddPdfFieldToStorageExporter exporter( blocks, identifier, latticeModel, initialVelocity, initialDensity, gl, layout, densityAdaptor, velocityAdaptor, shearRateAdaptor ); - python_coupling::for_each_noncopyable_type< LatticeModels > ( boost::ref(exporter) ); + python_coupling::for_each_noncopyable_type< LatticeModels > ( std::ref(exporter) ); if ( ! exporter.successful() ) { PyErr_SetString( PyExc_ValueError, "Adding Pdf Field failed."); throw error_already_set(); diff --git a/src/lbm/python/ExportBoundary.impl.h b/src/lbm/python/ExportBoundary.impl.h index 009bda5324524ea24c7c42ea8397b78b3f2ccd40..06845e35a29f9b4d9b5635944145766ea6e5e9f2 100644 --- a/src/lbm/python/ExportBoundary.impl.h +++ b/src/lbm/python/ExportBoundary.impl.h @@ -227,7 +227,7 @@ namespace internal } ExtendedBoundaryHandlingCreator creator( bs, name, pdfFieldID, flagFieldID ); - python_coupling::for_each_noncopyable_type<LatticeModels>( boost::ref( creator ) ); + python_coupling::for_each_noncopyable_type<LatticeModels>( std::ref( creator ) ); if ( ! creator.successful() ) { diff --git a/src/lbm/python/ExportSweeps.impl.h b/src/lbm/python/ExportSweeps.impl.h index fa01bf969cc7d9acce88e5eac7bd042da93d8c33..5f9440114375038cd2c75a17e82ef13dcb45ae83 100644 --- a/src/lbm/python/ExportSweeps.impl.h +++ b/src/lbm/python/ExportSweeps.impl.h @@ -221,7 +221,7 @@ namespace internal auto flagUidSet = python_coupling::uidSetFromStringContainer< FlagUID >( flagList ); CellwiseSweepCreator creator( bs, pdfFieldID, flagFieldStringID, velocityFieldStringID, flagUidSet ); - python_coupling::for_each_noncopyable_type<LatticeModel_FlagField_Pairs>( boost::ref( creator ) ); + python_coupling::for_each_noncopyable_type<LatticeModel_FlagField_Pairs>( std::ref( creator ) ); if ( creator.getResult() == object() ) { diff --git a/src/mesh/blockforest/BlockForestInitialization.h b/src/mesh/blockforest/BlockForestInitialization.h index 6f9018beb5617cbb98718e8c285a529eac9ede9e..1c39d1c2ec8c340e53647e36a20577c131fdbcd4 100644 --- a/src/mesh/blockforest/BlockForestInitialization.h +++ b/src/mesh/blockforest/BlockForestInitialization.h @@ -21,6 +21,10 @@ #pragma once +#include "BlockExclusion.h" +#include "mesh/MeshOperations.h" +#include "mesh/distance_octree/DistanceOctree.h" + #include "blockforest/StructuredBlockForest.h" #include "blockforest/SetupBlockForest.h" #include "blockforest/loadbalancing/StaticCurve.h" @@ -110,5 +114,37 @@ private: }; +template< typename MeshType > +shared_ptr<StructuredBlockForest> createStructuredBlockStorageInsideMesh( const shared_ptr< mesh::DistanceOctree< MeshType > > & distanceOctree, const real_t dx, const Vector3<uint_t> & blockSize ) +{ + ComplexGeometryStructuredBlockforestCreator creator( distanceOctree->getAABB(), Vector3<real_t>(dx), makeExcludeMeshExterior( distanceOctree, dx ) ); + return creator.createStructuredBlockForest( blockSize ); +} + + +template< typename MeshType > +shared_ptr<StructuredBlockForest> createStructuredBlockStorageOutsideMesh( const AABB & aabb, const shared_ptr< mesh::DistanceOctree< MeshType > > & distanceOctree, const real_t dx, const Vector3<uint_t> & blockSize ) +{ + ComplexGeometryStructuredBlockforestCreator creator( aabb, Vector3<real_t>(dx), makeExcludeMeshInterior( distanceOctree, dx ) ); + return creator.createStructuredBlockForest( blockSize ); +} + + +template< typename MeshType > +shared_ptr<StructuredBlockForest> createStructuredBlockStorageInsideMesh( const shared_ptr< mesh::DistanceOctree< MeshType > > & distanceOctree, const real_t dx, const uint_t targetNumRootBlocks ) +{ + ComplexGeometryStructuredBlockforestCreator creator( distanceOctree->getAABB(), Vector3<real_t>(dx), makeExcludeMeshExterior( distanceOctree, dx ) ); + return creator.createStructuredBlockForest( targetNumRootBlocks ); +} + + +template< typename MeshType > +shared_ptr<StructuredBlockForest> createStructuredBlockStorageOutsideMesh( const AABB & aabb, const shared_ptr< mesh::DistanceOctree< MeshType > > & distanceOctree, const real_t dx, const uint_t targetNumRootBlocks ) +{ + ComplexGeometryStructuredBlockforestCreator creator( aabb, Vector3<real_t>(dx), makeExcludeMeshInterior( distanceOctree, dx ) ); + return creator.createStructuredBlockForest( targetNumRootBlocks ); +} + + } // namespace mesh } // namespace walberla \ No newline at end of file diff --git a/src/mesh/boundary/BoundarySetup.cpp b/src/mesh/boundary/BoundarySetup.cpp index b8390b6b71ecf287821ab4f2694f5b6fcc628aea..c0edcc1ed81ce102e05eefb1556825730d39b582 100644 --- a/src/mesh/boundary/BoundarySetup.cpp +++ b/src/mesh/boundary/BoundarySetup.cpp @@ -27,6 +27,21 @@ namespace walberla { namespace mesh { + +BoundarySetup::BoundarySetup( const shared_ptr< StructuredBlockStorage > & structuredBlockStorage, const DistanceFunction & distanceFunction, const uint_t numGhostLayers ) + : structuredBlockStorage_( structuredBlockStorage ), distanceFunction_( distanceFunction ), numGhostLayers_( numGhostLayers ), cellVectorChunkSize_( size_t(1000) ) +{ + voxelize(); + + try { + auto & blockForest = dynamic_cast< StructuredBlockForest & >( *structuredBlockStorage_ ); + if( !blockForest.storesUniformBlockGrid() ) + refinementCorrection( blockForest ); + } + catch( const std::bad_cast & ) {} // If it's not a BlockForest no refinement correction is done +} + + void BoundarySetup::divideAndPushCellInterval( const CellInterval & ci, std::queue< CellInterval > & outputQueue ) { WALBERLA_ASSERT( !ci.empty() ); @@ -66,15 +81,15 @@ void BoundarySetup::allocateOrResetVoxelizationField() { if( voxelizationFieldId_ ) { - for( auto blockIt = structuredBlockStorage_->begin(); blockIt != structuredBlockStorage_->end(); ++blockIt ) + for( auto & block : *structuredBlockStorage_ ) { - VoxelizationField * voxelizationField = blockIt->getData< VoxelizationField >( *voxelizationFieldId_ ); + VoxelizationField * voxelizationField = block.getData< VoxelizationField >( *voxelizationFieldId_ ); voxelizationField->setWithGhostLayer( uint8_t(0) ); } } else { - voxelizationFieldId_ = make_shared< BlockDataID >( field::addToStorage< VoxelizationField >( structuredBlockStorage_, "flag field", uint8_t(0), field::zyxf, numGhostLayers_ ) ); + voxelizationFieldId_ = make_shared< BlockDataID >( field::addToStorage< VoxelizationField >( structuredBlockStorage_, "voxelization field", uint8_t(0), field::zyxf, numGhostLayers_ ) ); } WALBERLA_ASSERT_NOT_NULLPTR( voxelizationFieldId_ ); @@ -93,15 +108,15 @@ void BoundarySetup::voxelize() { allocateOrResetVoxelizationField(); - for( auto blockIt = structuredBlockStorage_->begin(); blockIt != structuredBlockStorage_->end(); ++blockIt ) + for( auto & block : *structuredBlockStorage_ ) { - VoxelizationField * voxelizationField = blockIt->getData< VoxelizationField >( *voxelizationFieldId_ ); + VoxelizationField * voxelizationField = block.getData< VoxelizationField >( *voxelizationFieldId_ ); WALBERLA_ASSERT_NOT_NULLPTR( voxelizationField ); WALBERLA_ASSERT_EQUAL( numGhostLayers_, voxelizationField->nrOfGhostLayers() ); CellInterval blockCi = voxelizationField->xyzSizeWithGhostLayer(); - structuredBlockStorage_->transformBlockLocalToGlobalCellInterval( blockCi, *blockIt ); + structuredBlockStorage_->transformBlockLocalToGlobalCellInterval( blockCi, block ); std::queue< CellInterval > ciQueue; ciQueue.push( blockCi ); @@ -112,7 +127,7 @@ void BoundarySetup::voxelize() WALBERLA_ASSERT( !curCi.empty(), "Cell Interval: " << curCi ); - AABB curAABB = structuredBlockStorage_->getAABBFromCellBB( curCi, structuredBlockStorage_->getLevel( *blockIt ) ); + AABB curAABB = structuredBlockStorage_->getAABBFromCellBB( curCi, structuredBlockStorage_->getLevel( block ) ); WALBERLA_ASSERT( !curAABB.empty(), "AABB: " << curAABB ); @@ -125,7 +140,7 @@ void BoundarySetup::voxelize() if( ( sqSignedDistance < real_t(0) ) ) { Cell localCell; - structuredBlockStorage_->transformGlobalToBlockLocalCell( localCell, *blockIt, curCi.min() ); + structuredBlockStorage_->transformGlobalToBlockLocalCell( localCell, block, curCi.min() ); voxelizationField->get( localCell ) = uint8_t(1); } @@ -140,7 +155,7 @@ void BoundarySetup::voxelize() { // clearly the cell interval is fully covered by the mesh CellInterval localCi; - structuredBlockStorage_->transformGlobalToBlockLocalCellInterval( localCi, *blockIt, curCi ); + structuredBlockStorage_->transformGlobalToBlockLocalCellInterval( localCi, block, curCi ); std::fill( voxelizationField->beginSliceXYZ( localCi ), voxelizationField->end(), uint8_t(1) ); ciQueue.pop(); @@ -163,6 +178,78 @@ void BoundarySetup::voxelize() } } +void BoundarySetup::refinementCorrection( StructuredBlockForest & blockForest ) +{ + if( blockForest.getNumberOfXCellsPerBlock() < uint_t( 16 ) + || blockForest.getNumberOfYCellsPerBlock() < uint_t( 16 ) + || blockForest.getNumberOfZCellsPerBlock() < uint_t( 16 ) ) + { + WALBERLA_ABORT( "The mesh boundary setup requires a block size of at least 16 in each dimension, when refinement is used!" ); + } + + for( auto & iBlock : blockForest ) + { + auto & block = dynamic_cast< blockforest::Block & >( iBlock ); + + const uint_t level = block.getLevel(); + + VoxelizationField * voxelizationField = block.getData< VoxelizationField >( *voxelizationFieldId_ ); + const CellInterval cells = voxelizationField->xyzSize(); + + std::vector< CellInterval > coarseRegions; + for( auto dir = stencil::D3Q27::beginNoCenter(); dir != stencil::D3Q27::end(); ++dir ) + { + const auto index = blockforest::getBlockNeighborhoodSectionIndex( dir.cx(), dir.cy(), dir.cz() ); + if( block.neighborhoodSectionHasLargerBlock( index ) ) + { + CellInterval coarseRegion( cells ); + for( uint_t i = 0; i != 3; ++i ) + { + const auto c = stencil::c[i][*dir]; + + if( c == -1 ) + { + coarseRegion.min()[i] -= cell_idx_c( numGhostLayers_ ); + coarseRegion.max()[i] = cells.min()[i] + cell_idx_c( 2 * numGhostLayers_ - 1 ); + } + else if( c == 1 ) + { + coarseRegion.min()[i] = cells.max()[i] - cell_idx_c( 2 * numGhostLayers_ - 1 ); + coarseRegion.max()[i] += cell_idx_c( numGhostLayers_ ); + } + } + coarseRegions.push_back( coarseRegion ); + } + } + + for( const CellInterval & coarseRegion : coarseRegions) + for( const Cell & cell : coarseRegion ) + { + Cell globalCell( cell ); + structuredBlockStorage_->transformBlockLocalToGlobalCell( globalCell, block ); + + Cell coarseCell( globalCell ); + for( uint_t i = 0; i < 3; ++i ) + { + if( coarseCell[i] < cell_idx_t(0) ) + { + coarseCell[i] = -( ( cell_idx_t(1) - coarseCell[i] ) >> 1 ); + } + else + { + coarseCell[i] >>= 1; + } + } + + Vector3< real_t > coarseCenter; + structuredBlockStorage_->getCellCenter( coarseCenter, coarseCell, level - uint_t(1) ); + structuredBlockStorage_->mapToPeriodicDomain( coarseCenter ); + + voxelizationField->get( cell ) = distanceFunction_( coarseCenter ) < real_t(0) ? uint8_t(1) : uint8_t(0); + } + } +} + void BoundarySetup::writeVTKVoxelfile( const std::string & identifier, bool writeGhostLayers, const std::string & baseFolder, const std::string & executionFolder ) { diff --git a/src/mesh/boundary/BoundarySetup.h b/src/mesh/boundary/BoundarySetup.h index 08840ed0ae24502e7248d9831351b955d15f0d30..1512fe618a89281707dae40e6c6465b01fb0258d 100644 --- a/src/mesh/boundary/BoundarySetup.h +++ b/src/mesh/boundary/BoundarySetup.h @@ -23,6 +23,8 @@ #include "BoundaryInfo.h" +#include "blockforest/StructuredBlockForest.h" + #include "core/DataTypes.h" #include "core/cell/CellInterval.h" @@ -50,11 +52,7 @@ public: enum Location { INSIDE, OUTSIDE }; - BoundarySetup( const shared_ptr< StructuredBlockStorage > & structuredBlockStorage, const DistanceFunction & distanceFunction, const uint_t numGhostLayers ) - : structuredBlockStorage_( structuredBlockStorage ), distanceFunction_( distanceFunction ), numGhostLayers_( numGhostLayers ), cellVectorChunkSize_( size_t(1000) ) - { - voxelize(); - } + BoundarySetup( const shared_ptr< StructuredBlockStorage > & structuredBlockStorage, const DistanceFunction & distanceFunction, const uint_t numGhostLayers ); ~BoundarySetup() { deallocateVoxelizationField(); } @@ -79,12 +77,13 @@ private: void deallocateVoxelizationField(); void voxelize(); + void refinementCorrection( StructuredBlockForest & blockForest ); shared_ptr< StructuredBlockStorage > structuredBlockStorage_; shared_ptr< BlockDataID > voxelizationFieldId_; - DistanceFunction distanceFunction_; // function providing the squared signed distance to an object + DistanceFunction distanceFunction_; /// function providing the squared signed distance to an object uint_t numGhostLayers_; - size_t cellVectorChunkSize_; + size_t cellVectorChunkSize_; /// Number of boundary cells which are setup simultaneously }; @@ -92,12 +91,12 @@ private: template< typename BoundaryHandlingType > void BoundarySetup::setDomainCells( const BlockDataID boundaryHandlingId, const Location domainLocation ) { - for( auto blockIt = structuredBlockStorage_->begin(); blockIt != structuredBlockStorage_->end(); ++blockIt ) + for( auto & block : *structuredBlockStorage_ ) { - BoundaryHandlingType * boundaryHandling = blockIt->getData< BoundaryHandlingType >( boundaryHandlingId ); + BoundaryHandlingType * boundaryHandling = block.getData< BoundaryHandlingType >( boundaryHandlingId ); WALBERLA_CHECK_NOT_NULLPTR( boundaryHandling, "boundaryHandlingId invalid!" ); - const VoxelizationField * voxelizationField = blockIt->getData< VoxelizationField >( *voxelizationFieldId_ ); + const VoxelizationField * voxelizationField = block.getData< VoxelizationField >( *voxelizationFieldId_ ); WALBERLA_ASSERT_NOT_NULLPTR( voxelizationField ); WALBERLA_CHECK_LESS_EQUAL( numGhostLayers_, boundaryHandling->getFlagField()->nrOfGhostLayers(), "You want to use mesh boundary setup with " \ << numGhostLayers_ << " but your flag field has only " << boundaryHandling->getFlagField()->nrOfGhostLayers() << " ghost layers!" ); @@ -111,7 +110,7 @@ void BoundarySetup::setDomainCells( const BlockDataID boundaryHandlingId, const for( cell_idx_t x = -cell_idx_c( numGhostLayers_ ); x < cell_idx_c( voxelizationField->xSize() + numGhostLayers_ ); ++x ) { if( voxelizationField->get( x, y, z ) == domainValue ) - domainCells.push_back( Cell(x,y,z) ); + domainCells.emplace_back( x, y, z ); if( domainCells.size() > cellVectorChunkSize_ ) { @@ -128,13 +127,13 @@ void BoundarySetup::setDomainCells( const BlockDataID boundaryHandlingId, const template<typename FlagField_T> void BoundarySetup::setFlag( const BlockDataID flagFieldID, field::FlagUID flagUID, Location boundaryLocation ) { - for( auto blockIt = structuredBlockStorage_->begin(); blockIt != structuredBlockStorage_->end(); ++blockIt ) + for( auto & block : *structuredBlockStorage_ ) { - FlagField_T * flagField = blockIt->getData< FlagField_T >( flagFieldID ); + FlagField_T * flagField = block.getData< FlagField_T >( flagFieldID ); WALBERLA_CHECK_NOT_NULLPTR( flagField, "flagFieldID invalid!" ); auto flag = flagField->getFlag(flagUID); - const VoxelizationField * voxelizationField = blockIt->getData< VoxelizationField >( *voxelizationFieldId_ ); + const VoxelizationField * voxelizationField = block.getData< VoxelizationField >( *voxelizationFieldId_ ); WALBERLA_ASSERT_NOT_NULLPTR( voxelizationField ); WALBERLA_CHECK_LESS_EQUAL( numGhostLayers_, flagField->nrOfGhostLayers(), "You want to use mesh boundary setup with " \ << numGhostLayers_ << " but your flag field has only " << flagField->nrOfGhostLayers() << " ghost layers!" ); @@ -155,12 +154,12 @@ void BoundarySetup::setFlag( const BlockDataID flagFieldID, field::FlagUID flagU template< typename BoundaryHandlingType, typename BoundaryFunction, typename Stencil > void BoundarySetup::setBoundaries( const BlockDataID boundaryHandlingID, const BoundaryFunction & boundaryFunction, Location boundaryLocation ) { - for( auto blockIt = structuredBlockStorage_->begin(); blockIt != structuredBlockStorage_->end(); ++blockIt ) + for( auto & block : *structuredBlockStorage_ ) { - BoundaryHandlingType * boundaryHandling = blockIt->getData< BoundaryHandlingType >( boundaryHandlingID ); + BoundaryHandlingType * boundaryHandling = block.getData< BoundaryHandlingType >( boundaryHandlingID ); WALBERLA_CHECK_NOT_NULLPTR( boundaryHandling, "boundaryHandlingId invalid!" ); - const VoxelizationField * voxelizationField = blockIt->getData< VoxelizationField >( *voxelizationFieldId_ ); + const VoxelizationField * voxelizationField = block.getData< VoxelizationField >( *voxelizationFieldId_ ); WALBERLA_ASSERT_NOT_NULLPTR( voxelizationField ); WALBERLA_CHECK_LESS_EQUAL( numGhostLayers_, boundaryHandling->getFlagField()->nrOfGhostLayers(), "You want to use mesh boundary setup with " \ << numGhostLayers_ << " but your flag field has only " << boundaryHandling->getFlagField()->nrOfGhostLayers() << " ghost layers!" ); @@ -182,7 +181,7 @@ void BoundarySetup::setBoundaries( const BlockDataID boundaryHandlingID, const B const Cell neighborCell = cell + *dirIt; if( blockCi.contains( neighborCell ) && voxelizationField->get( neighborCell ) == domainValue ) { - const Vector3< real_t > cellCenter = structuredBlockStorage_->getBlockLocalCellCenter( *blockIt, cell ); + const Vector3< real_t > cellCenter = structuredBlockStorage_->getBlockLocalCellCenter( block, cell ); const BoundaryInfo & bi = boundaryFunction( cellCenter ); const auto boundaryMask = boundaryHandling->getBoundaryMask( bi.getUid() ); diff --git a/src/mesh/pe/Types.h b/src/mesh/pe/Types.h index 842ba1132befa7e72d0d09f7c50a4889406d693b..6d94fad9c463f5ee0ff1bd645bf8d7e16ec18834 100644 --- a/src/mesh/pe/Types.h +++ b/src/mesh/pe/Types.h @@ -19,6 +19,8 @@ // //====================================================================================================================== +#include <memory> + namespace walberla { namespace mesh { namespace pe { @@ -28,6 +30,7 @@ class ConvexPolyhedron; typedef ConvexPolyhedron ConvexPolyhedronType; //!< Type of the convex polyhedron geometric primitive. typedef ConvexPolyhedron* ConvexPolyhedronID; //!< Handle for a convexpolyhedron primitive. typedef const ConvexPolyhedron* ConstConvexPolyhedronID; //!< Handle for a constant convex polyhedron primitive. +using ConvexPolyhedronPtr = std::unique_ptr<ConvexPolyhedron>; } // namespace pe } // namespace mesh diff --git a/src/mesh/pe/communication/ConvexPolyhedron.h b/src/mesh/pe/communication/ConvexPolyhedron.h index ef9bbb21cf1b6f4f8883a867395dbee0b8f5080f..df14bb1762f9755225f004d2730a76be617ed236 100644 --- a/src/mesh/pe/communication/ConvexPolyhedron.h +++ b/src/mesh/pe/communication/ConvexPolyhedron.h @@ -69,16 +69,17 @@ namespace pe { namespace communication { template<> -inline mesh::pe::ConvexPolyhedronID instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, mesh::pe::ConvexPolyhedronID& newBody ) +inline mesh::pe::ConvexPolyhedronPtr instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, mesh::pe::ConvexPolyhedronID& newBody ) { mesh::pe::ConvexPolyhedronParameters subobjparam; unmarshal( buffer, subobjparam ); correctBodyPosition(domain, block.center(), subobjparam.gpos_); - newBody = new mesh::pe::ConvexPolyhedron( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.mesh_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ ); - newBody->setLinearVel( subobjparam.v_ ); - newBody->setAngularVel( subobjparam.w_ ); - newBody->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ ); - return newBody; + auto cp = std::make_unique<mesh::pe::ConvexPolyhedron>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.mesh_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ ); + cp->setLinearVel( subobjparam.v_ ); + cp->setAngularVel( subobjparam.w_ ); + cp->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ ); + newBody = static_cast<mesh::pe::ConvexPolyhedronID>(cp.get()); + return cp; } } // namespace communication diff --git a/src/mesh/pe/rigid_body/ConvexPolyhedronFactory.cpp b/src/mesh/pe/rigid_body/ConvexPolyhedronFactory.cpp index 959215e94d18a34d34741e2a99f3b590e4a66d38..63c268ae6031a333d50e2720d8dacf8adeb97b93 100644 --- a/src/mesh/pe/rigid_body/ConvexPolyhedronFactory.cpp +++ b/src/mesh/pe/rigid_body/ConvexPolyhedronFactory.cpp @@ -65,7 +65,7 @@ ConvexPolyhedronID createConvexPolyhedron( BodyStorage& globalStorage, BlockStor { WALBERLA_ASSERT_UNEQUAL( ConvexPolyhedron::getStaticTypeID(), std::numeric_limits<id_t>::max(), "ConvexPolyhedron TypeID not initalized!"); - ConvexPolyhedronID poly = NULL; + ConvexPolyhedronID poly = nullptr; Vec3 centroid = toWalberla( computeCentroid( mesh ) ); translate( mesh, -centroid ); @@ -78,33 +78,30 @@ ConvexPolyhedronID createConvexPolyhedron( BodyStorage& globalStorage, BlockStor WALBERLA_CHECK_EQUAL(communicating, false, "Global bodies can not be communicating!" ); WALBERLA_CHECK_EQUAL(infiniteMass, true, "Global bodies must have infinite mass!" ); - poly = new ConvexPolyhedron(sid, uid, gpos, Vec3(0,0,0), Quat(), mesh, material, global, false, true); - globalStorage.add(poly); + auto cp = std::make_unique<ConvexPolyhedron>(sid, uid, gpos, Vec3(0,0,0), Quat(), mesh, material, global, false, true); + poly = static_cast<ConvexPolyhedronID>(&globalStorage.add(std::move(cp))); } else { - for (auto it = blocks.begin(); it != blocks.end(); ++it){ - IBlock* block = (&(*it)); - if (block->getAABB().contains(gpos)) + for (auto& block : blocks){ + if (block.getAABB().contains(gpos)) { const id_t sid( UniqueID<RigidBody>::create() ); - Storage* bs = block->getData<Storage>(storageID); - poly = new ConvexPolyhedron(sid, uid, gpos, Vec3(0,0,0), Quat(), mesh, material, global, communicating, infiniteMass); - poly->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block->getId().getID())); - (*bs)[0].add(poly); + BodyStorage& bs = (*block.getData<Storage>(storageID))[0]; + auto cp = std::make_unique<ConvexPolyhedron>(sid, uid, gpos, Vec3(0,0,0), Quat(), mesh, material, global, communicating, infiniteMass); + cp->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID())); + poly = static_cast<ConvexPolyhedronID>(&bs.add( std::move(cp) ) ); } } } - if (poly != NULL) + if (poly != nullptr) { // Logging the successful creation of the box WALBERLA_LOG_DETAIL( "Created ConvexPolyhedron " << poly->getSystemID() << "\n" << " User-ID = " << uid << "\n" << " Global position = " << gpos << "\n" - << " side length = " << lengths << "\n" - << " LinVel = " << box->getLinearVel() << "\n" << " Material = " << Material::getName( material ) ); } diff --git a/src/mesh/pe/vtk/CommonDataSources.h b/src/mesh/pe/vtk/CommonDataSources.h index d2454c15cd6a59e836e6f97dba550b0d6696281e..bf86f2cddcde9b3283cf454cab882896212f0c42 100644 --- a/src/mesh/pe/vtk/CommonDataSources.h +++ b/src/mesh/pe/vtk/CommonDataSources.h @@ -189,6 +189,8 @@ public: LinearVelocityFaceDataSource( const std::string & _name = "linearVelocity" ) : Base( _name ) { } + virtual ~LinearVelocityFaceDataSource() = default; + virtual uint_t numComponents() { return uint_t(3); } virtual void getData( const MeshType & /*mesh*/, const Faces & faces, std::vector<value_type> & data, const BodyPointerFPropManager & bodyPointer ) @@ -249,6 +251,8 @@ public: AngularVelocityFaceDataSource( const std::string & _name = "angularVelocity" ) : Base( _name ) { } + virtual ~AngularVelocityFaceDataSource() = default; + virtual uint_t numComponents() { return uint_t(3); } virtual void getData( const MeshType & /*mesh*/, const Faces & faces, std::vector<value_type> & data, const BodyPointerFPropManager & bodyPointer ) @@ -279,6 +283,8 @@ public: SurfaceVelocityVertexDataSource( const std::string & _name = "surfaceVelocity" ) : Base( _name ) { } + virtual ~SurfaceVelocityVertexDataSource() = default; + virtual uint_t numComponents() { return uint_t(3); } virtual void getData( const MeshType & mesh, const Vertices & vertices, std::vector<value_type> & data, const BodyPointerVPropManager & bodyPointer ) diff --git a/src/mesh/pe/vtk/PeVTKMeshWriter.h b/src/mesh/pe/vtk/PeVTKMeshWriter.h index 55721ae20d67cdad08ed468ab8fe7378a4818e47..72685c362bbd486418b9edd1002db50347f1c712 100644 --- a/src/mesh/pe/vtk/PeVTKMeshWriter.h +++ b/src/mesh/pe/vtk/PeVTKMeshWriter.h @@ -186,16 +186,16 @@ protected: const walberla::pe::BodyStorage & bodyStorage = (*storage)[0]; for(auto bodyIt = bodyStorage.begin(); bodyIt != bodyStorage.end(); ++bodyIt) { - if (!bodyFilter_(**bodyIt)) continue; + if (!bodyFilter_(*bodyIt)) continue; newVertices.clear(); newFaces.clear(); - tesselation_( **bodyIt, *mesh_, newVertices, newFaces ); + tesselation_( *bodyIt, *mesh_, newVertices, newFaces ); for( const auto & fh: newFaces ) - faceBodyPointer_[fh] = *bodyIt; + faceBodyPointer_[fh] = bodyIt.getBodyID(); for( const auto & vh: newVertices ) - vertexBodyPointer_[vh] = *bodyIt; + vertexBodyPointer_[vh] = bodyIt.getBodyID(); } } diff --git a/src/mesh/vtk/VTKMeshWriter.h b/src/mesh/vtk/VTKMeshWriter.h index cf01acf7e4c5451faa2459703a845228f9a9a8e0..129c456a1696a408484a67fb6b26a6933bfa6c6a 100644 --- a/src/mesh/vtk/VTKMeshWriter.h +++ b/src/mesh/vtk/VTKMeshWriter.h @@ -52,6 +52,7 @@ public: { public: DataSource( const std::string & _name ) : name_( _name ) { } + virtual ~DataSource() = default; typedef T value_type; virtual uint_t numComponents() = 0; const std::string & name() { return name_; } @@ -67,6 +68,7 @@ public: typedef typename VTKMeshWriter::Vertices Vertices; VertexDataSource( const std::string & _name ) : DataSource<T>( _name ) { } + virtual ~VertexDataSource() = default; virtual void getData( const MeshType &, const Vertices & vertices, std::vector<T> & ) = 0; }; @@ -78,6 +80,7 @@ public: typedef typename VTKMeshWriter::Faces Faces; FaceDataSource( const std::string & _name ) : DataSource<T>( _name ) { } + virtual ~FaceDataSource() = default; virtual void getData( const MeshType &, const Faces & faces, std::vector<T> & ) = 0; }; diff --git a/src/pde/iterations/VCycles.h b/src/pde/iterations/VCycles.h index eca2b908fc5420cb24b1889e0bba71c2c2cbe86d..1d6f12fa61b1d5225cbd053584d9830139a819a2 100644 --- a/src/pde/iterations/VCycles.h +++ b/src/pde/iterations/VCycles.h @@ -32,6 +32,7 @@ #include "pde/sweeps/RBGSFixedStencil.h" #include "pde/sweeps/RBGS.h" +#include "pde/sweeps/Multigrid.h" #include <functional> @@ -41,7 +42,21 @@ namespace walberla { namespace pde { -template< typename Stencil_T > +//********************************************************************************************************************** +/*! + * \brief Class for multigrid V-cycle + * + * \tparam Stencil_T The stencil used for the discrete operator + * \tparam OperatorCoarsening_T The coarsening operator to use, defaults to direct coarsening + * \tparam Restrict_T The restriction operator to use + * \tparam ProlongateAndCorrect_T The prolongation and correction operator to use + */ +//********************************************************************************************************************** +template< typename Stencil_T, + typename OperatorCoarsening_T = CoarsenStencilFieldsDCA<Stencil_T>, + typename Restrict_T = Restrict<Stencil_T>, + typename ProlongateAndCorrect_T = ProlongateAndCorrect<Stencil_T> + > class VCycles { public: @@ -50,6 +65,21 @@ public: typedef std::vector< real_t > Weight_T; typedef GhostLayerField< real_t, Stencil_T::Size > StencilField_T; + //******************************************************************************************************************* + /*! Creates a multigrid V-cycle with a fixed stencil + * \param blocks the block storage where the fields are stored + * \param uFieldId the block data id of the solution field on the finest level + * \param fFieldId the block data id of the right-hand side field on the finest level + * \param weights vector of stencil weights for the discrete operator + * \param iterations maximum number of V-cycles to perform + * \param numLvl number of grid levels to use (including the finest level) + * \param preSmoothingIters number of Gauss-Seidel iterations before restriction + * \param postSmoothingIters number of Gauss-Seidel iterations after prolongation + * \param coarseIters number of Conjugate Gradient iterations on coarsest grid + * \param residualNorm function that returns the norm of the current residuum + * \param residualNormThreshold norm threshold below which the iteration is terminated + * \param residualCheckFrequency how often to check whether the threshold has been reached + *******************************************************************************************************************/ VCycles( shared_ptr< StructuredBlockForest > blocks, const BlockDataID & uFieldId, const BlockDataID & fFieldId, const Weight_T weights, const uint_t iterations, const uint_t numLvl, @@ -59,8 +89,25 @@ public: const Set<SUID> & requiredSelectors = Set<SUID>::emptySet(), const Set<SUID> & incompatibleSelectors = Set<SUID>::emptySet() ); + //******************************************************************************************************************* + /*! Creates a multigrid V-cycle with a stencil field + * \param blocks the block storage where the fields are stored + * \param uFieldId the block data id of the solution field on the finest level + * \param fFieldId the block data id of the right-hand side field on the finest level + * \param stencilFieldId the block data id of the stencil field for the finest level. + * The values stored in the field must not change after this class has been constructed. + * \param operatorCoarsening function that performs the stencil coarsening + * \param iterations maximum number of V-cycles to perform + * \param numLvl number of grid levels to use (including the finest level) + * \param preSmoothingIters number of Gauss-Seidel iterations before restriction + * \param postSmoothingIters number of Gauss-Seidel iterations after prolongation + * \param coarseIters number of Conjugate Gradient iterations on coarsest grid + * \param residualNorm function that returns the norm of the current residuum + * \param residualNormThreshold norm threshold below which the iteration is terminated + * \param residualCheckFrequency how often to check whether the threshold has been reached + *******************************************************************************************************************/ VCycles( shared_ptr< StructuredBlockForest > blocks, const BlockDataID & uFieldId, const BlockDataID & fFieldId, - const BlockDataID & stencilFieldId, + const BlockDataID & stencilFieldId, const OperatorCoarsening_T & operatorCoarsening, const uint_t iterations, const uint_t numLvl, const uint_t preSmoothingIters, const uint_t postSmoothingIters, const uint_t coarseIters, const std::function< real_t () > & residualNorm, @@ -76,9 +123,7 @@ public: const std::vector<real_t> & convergenceRate() { return convergenceRate_; } static Vector3<uint_t> getSizeForLevel( const uint_t level, const shared_ptr< StructuredBlockStorage > & blocks, IBlock * const block ); -protected: - - void coarsenStencilFields(); +private: StructuredBlockForest & blocks_; std::vector< Weight_T > weights_; diff --git a/src/pde/iterations/VCycles.impl.h b/src/pde/iterations/VCycles.impl.h index a35cf35779f8dd3396a6792a4fedeaad7e7957e3..f202d89e20b45e8c3cd26fb9398b0acbff6fb1cc 100644 --- a/src/pde/iterations/VCycles.impl.h +++ b/src/pde/iterations/VCycles.impl.h @@ -39,10 +39,10 @@ namespace walberla { namespace pde { -template< typename Stencil_T > -VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const BlockDataID & uFieldId, const BlockDataID & fFieldId, - const Weight_T weights, - const uint_t iterations, const uint_t numLvl, +template< typename Stencil_T, typename OperatorCoarsening_T, typename Restrict_T, typename ProlongateAndCorrect_T > +VCycles< Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T >::VCycles( + shared_ptr< StructuredBlockForest > blocks, const BlockDataID & uFieldId, const BlockDataID & fFieldId, + const Weight_T weights, const uint_t iterations, const uint_t numLvl, const uint_t preSmoothingIters, const uint_t postSmoothingIters, const uint_t coarseIters, const std::function< real_t () > & residualNorm, const real_t residualNormThreshold, const uint_t residualCheckFrequency, @@ -54,6 +54,9 @@ VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const iterationsPerformed_( uint_t(0) ), thresholdReached_( false ), residualNorm_( residualNorm ), convergenceRate_(), stencilId_(), requiredSelectors_( requiredSelectors ), incompatibleSelectors_( incompatibleSelectors ) { + + static_assert(std::is_same<OperatorCoarsening_T, CoarsenStencilFieldsDCA<Stencil_T>>::value, "Use of weight requires DCA, use constructor with stencil field if you want to employ GCA"); + // Set up fields for finest level uId_.push_back( uFieldId ); fId_.push_back( fFieldId ); @@ -87,7 +90,7 @@ VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const // Set up fields for coarser levels for ( uint_t lvl = 1; lvl < numLvl; ++lvl ) { - auto getSize = std::bind(VCycles<Stencil_T>::getSizeForLevel, lvl, std::placeholders::_1, std::placeholders::_2); + auto getSize = std::bind(VCycles<Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T>::getSizeForLevel, lvl, std::placeholders::_1, std::placeholders::_2); uId_.push_back( field::addToStorage< PdeField_T >( blocks, "u_"+boost::lexical_cast<std::string>(lvl), getSize, real_t(0), field::zyxf, uint_t(1) ) ); fId_.push_back( field::addToStorage< PdeField_T >( blocks, "f_"+boost::lexical_cast<std::string>(lvl), getSize, real_t(0), field::zyxf, uint_t(1) ) ); rId_.push_back( field::addToStorage< PdeField_T >( blocks, "r_"+boost::lexical_cast<std::string>(lvl), getSize, real_t(0), field::zyxf, uint_t(1) ) ); @@ -100,7 +103,7 @@ VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const } // Set up fields for CG on coarsest level - auto getFineSize = std::bind(VCycles<Stencil_T>::getSizeForLevel, numLvl-1, std::placeholders::_1, std::placeholders::_2); + auto getFineSize = std::bind(VCycles<Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T>::getSizeForLevel, numLvl-1, std::placeholders::_1, std::placeholders::_2); dId_ = field::addToStorage< PdeField_T >( blocks, "d", getFineSize, real_t(0), field::zyxf, uint_t(1) ); zId_ = field::addToStorage< PdeField_T >( blocks, "z", getFineSize, real_t(0), field::zyxf, uint_t(1) ); @@ -132,9 +135,9 @@ VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const for (uint_t lvl = 0; lvl < numLvl-1; ++lvl) { computeResidual_.push_back( ComputeResidualFixedStencil< Stencil_T >( blocks, uId_[lvl], fId_[lvl], weights_[lvl], rId_[lvl] ) ); - restrict_.push_back( Restrict< Stencil_T >(blocks, rId_[lvl], fId_[lvl+1] ) ); + restrict_.push_back( Restrict_T(blocks, rId_[lvl], fId_[lvl+1] ) ); zeroize_.push_back( Zeroize(blocks, uId_[lvl+1]) ); - prolongateAndCorrect_.push_back( ProlongateAndCorrect< Stencil_T >(blocks, uId_[lvl+1], uId_[lvl]) ); + prolongateAndCorrect_.push_back( ProlongateAndCorrect_T(blocks, uId_[lvl+1], uId_[lvl]) ); } // Set up CG coarse-grid iteration @@ -145,9 +148,10 @@ VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const -template< typename Stencil_T > -VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const BlockDataID & uFieldId, const BlockDataID & fFieldId, - const BlockDataID & stencilFieldId, +template< typename Stencil_T, typename OperatorCoarsening_T, typename Restrict_T, typename ProlongateAndCorrect_T > +VCycles< Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T >::VCycles( + shared_ptr< StructuredBlockForest > blocks, const BlockDataID & uFieldId, const BlockDataID & fFieldId, + const BlockDataID & stencilFieldId, const OperatorCoarsening_T & operatorCoarsening, const uint_t iterations, const uint_t numLvl, const uint_t preSmoothingIters, const uint_t postSmoothingIters, const uint_t coarseIters, const std::function< real_t () > & residualNorm, @@ -192,17 +196,19 @@ VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const // Set up fields for coarser levels for ( uint_t lvl = 1; lvl < numLvl; ++lvl ) { - auto getSize = std::bind(VCycles<Stencil_T>::getSizeForLevel, lvl, std::placeholders::_1, std::placeholders::_2); + auto getSize = std::bind(VCycles<Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T>::getSizeForLevel, lvl, std::placeholders::_1, std::placeholders::_2); uId_.push_back( field::addToStorage< PdeField_T >( blocks, "u_"+boost::lexical_cast<std::string>(lvl), getSize, real_t(0), field::zyxf, uint_t(1) ) ); fId_.push_back( field::addToStorage< PdeField_T >( blocks, "f_"+boost::lexical_cast<std::string>(lvl), getSize, real_t(0), field::zyxf, uint_t(1) ) ); rId_.push_back( field::addToStorage< PdeField_T >( blocks, "r_"+boost::lexical_cast<std::string>(lvl), getSize, real_t(0), field::zyxf, uint_t(1) ) ); stencilId_.push_back( field::addToStorage< StencilField_T >( blocks, "w_"+boost::lexical_cast<std::string>(lvl), getSize, real_t(0), field::zyxf, uint_t(1) ) ); } - coarsenStencilFields(); // scaling by ( 1/h^2 )^lvl + // CoarsenStencilFieldsDCA<Stencil_T>( blocks, stencilId_, numLvl, uint_t(2)) (); // scaling by ( 1/h^2 )^lvl + // CoarsenStencilFieldsGCA<Stencil_T>( blocks, stencilId_, numLvl, real_t(2)) (); + operatorCoarsening(stencilId_); // Set up fields for CG on coarsest level - auto getFineSize = std::bind(VCycles<Stencil_T>::getSizeForLevel, numLvl-1, std::placeholders::_1, std::placeholders::_2); + auto getFineSize = std::bind(VCycles<Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T>::getSizeForLevel, numLvl-1, std::placeholders::_1, std::placeholders::_2); dId_ = field::addToStorage< PdeField_T >( blocks, "d", getFineSize, real_t(0), field::zyxf, uint_t(1) ); zId_ = field::addToStorage< PdeField_T >( blocks, "z", getFineSize, real_t(0), field::zyxf, uint_t(1) ); @@ -234,9 +240,9 @@ VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const for (uint_t lvl = 0; lvl < numLvl-1; ++lvl) { computeResidual_.push_back( ComputeResidual< Stencil_T >( blocks, uId_[lvl], fId_[lvl], stencilId_[lvl], rId_[lvl] ) ); - restrict_.push_back( Restrict< Stencil_T >(blocks, rId_[lvl], fId_[lvl+1] ) ); + restrict_.push_back( Restrict_T(blocks, rId_[lvl], fId_[lvl+1] ) ); zeroize_.push_back( Zeroize(blocks, uId_[lvl+1]) ); - prolongateAndCorrect_.push_back( ProlongateAndCorrect< Stencil_T >(blocks, uId_[lvl+1], uId_[lvl]) ); + prolongateAndCorrect_.push_back( ProlongateAndCorrect_T(blocks, uId_[lvl+1], uId_[lvl]) ); } // Set up CG coarse-grid iteration @@ -247,8 +253,8 @@ VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const -template< typename Stencil_T > -void VCycles< Stencil_T >::operator()() +template< typename Stencil_T, typename OperatorCoarsening_T, typename Restrict_T, typename ProlongateAndCorrect_T > +void VCycles< Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T >::operator()() { WALBERLA_LOG_PROGRESS_ON_ROOT( "Starting VCycle iteration with a maximum number of " << iterations_ << " cycles and " << numLvl_ << " levels" ); thresholdReached_ = false; @@ -300,32 +306,8 @@ void VCycles< Stencil_T >::operator()() -template< typename Stencil_T > -void VCycles< Stencil_T >::coarsenStencilFields() -{ - const real_t scalingFactor = real_t(0.25); // scaling by ( 1/h^2 )^lvl - - WALBERLA_ASSERT_EQUAL(numLvl_, stencilId_.size(), "This function can only be called when operating with stencil fields!"); - - for ( uint_t lvl = 1; lvl < numLvl_; ++lvl ) - { - for( auto block = blocks_.begin( requiredSelectors_, incompatibleSelectors_ ); block != blocks_.end(); ++block ) - { - StencilField_T * fine = block->template getData< StencilField_T >( stencilId_[lvl-1] ); - StencilField_T * coarse = block->template getData< StencilField_T >( stencilId_[lvl] ); - - WALBERLA_FOR_ALL_CELLS_XYZ(coarse, - for( auto dir = Stencil_T::begin(); dir != Stencil_T::end(); ++dir ) - coarse->get(x,y,z, dir.toIdx()) = scalingFactor * fine->get(x,y,z, dir.toIdx()); - ) - } - } -} - - - -template< typename Stencil_T > -void VCycles< Stencil_T >::VCycle() +template< typename Stencil_T, typename OperatorCoarsening_T, typename Restrict_T, typename ProlongateAndCorrect_T > +void VCycles< Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T >::VCycle() { // pre-smoothen -- go from fine to coarse for (uint_t l = 0; l < numLvl_-1; ++l) @@ -376,8 +358,8 @@ void VCycles< Stencil_T >::VCycle() -template< typename Stencil_T > -Vector3<uint_t> VCycles< Stencil_T >::getSizeForLevel( const uint_t level, const shared_ptr< StructuredBlockStorage > & blocks, IBlock * const block ) +template< typename Stencil_T, typename OperatorCoarsening_T, typename Restrict_T, typename ProlongateAndCorrect_T > +Vector3<uint_t> VCycles< Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T >::getSizeForLevel( const uint_t level, const shared_ptr< StructuredBlockStorage > & blocks, IBlock * const block ) { Vector3<uint_t> cells( blocks->getNumberOfXCells( *block ), blocks->getNumberOfYCells( *block ), blocks->getNumberOfZCells( *block ) ); diff --git a/src/pde/sweeps/Multigrid.h b/src/pde/sweeps/Multigrid.h index 2398790832454c2f90eb91a7098c2ce8f678afaa..58d4d8f031afa649526cc3814b1115e9b8d6992b 100644 --- a/src/pde/sweeps/Multigrid.h +++ b/src/pde/sweeps/Multigrid.h @@ -31,6 +31,13 @@ namespace pde { +//********************************************************************************************************************** +/*! + * \brief Restriction sweep for multigrid + * + * \tparam Stencil_T The stencil used for the discrete operator + */ +//********************************************************************************************************************** template< typename Stencil_T > class Restrict { @@ -38,6 +45,11 @@ public: typedef GhostLayerField< real_t, 1 > Field_T; + //******************************************************************************************************************* + /* \param blocks the block storage where the fields are stored + * \param fineFieldId the block data id of the fine field + * \param coarseFieldId the block data id of the coarse field + *******************************************************************************************************************/ Restrict( const shared_ptr< domain_decomposition::StructuredBlockStorage > & blocks, const BlockDataID & fineFieldId, const BlockDataID & coarseFieldId ) : blocks_( blocks ), fineFieldId_( fineFieldId ), coarseFieldId_( coarseFieldId ) {} @@ -53,6 +65,13 @@ private: +//********************************************************************************************************************** +/*! + * \brief Prolongation and correction sweep for multigrid + * + * \tparam Stencil_T The stencil used for the discrete operator + */ +//********************************************************************************************************************** template< typename Stencil_T > class ProlongateAndCorrect { @@ -60,6 +79,11 @@ public: typedef GhostLayerField< real_t, 1 > Field_T; + //******************************************************************************************************************* + /* \param blocks the block storage where the fields are stored + * \param coarseFieldId the block data id of the coarse field + * \param fineFieldId the block data id of the fine field + *******************************************************************************************************************/ ProlongateAndCorrect( const shared_ptr< domain_decomposition::StructuredBlockStorage > & blocks, const BlockDataID & coarseFieldId, const BlockDataID & fineFieldId ) : blocks_( blocks ), fineFieldId_( fineFieldId ), coarseFieldId_( coarseFieldId ) {} @@ -75,6 +99,13 @@ private: +//********************************************************************************************************************** +/*! + * \brief Residual calculation sweep for multigrid with stencil field + * + * \tparam Stencil_T The stencil used for the discrete operator + */ +//********************************************************************************************************************** template< typename Stencil_T > class ComputeResidual { @@ -83,6 +114,13 @@ public: typedef GhostLayerField< real_t, 1 > Field_T; typedef GhostLayerField< real_t, Stencil_T::Size > StencilField_T; + //******************************************************************************************************************* + /* \param blocks the block storage where the fields are stored + * \param uId the block data id of the solution field + * \param fId the block data id of the right-hand side field + * \param stencilId the block data id of the stencil field + * \param rId the block data id of the residual field + *******************************************************************************************************************/ ComputeResidual( const shared_ptr< domain_decomposition::StructuredBlockStorage > & blocks, const BlockDataID & uId, const BlockDataID & fId, const BlockDataID & stencilId, const BlockDataID & rId ) : blocks_( blocks ), uId_( uId ), fId_( fId ), stencilId_( stencilId ), rId_( rId ) @@ -101,6 +139,13 @@ private: +//********************************************************************************************************************** +/*! + * \brief Residual calculation sweep for multigrid with fixed stencil weights + * + * \tparam Stencil_T The stencil used for the discrete operator + */ +//********************************************************************************************************************** template< typename Stencil_T > class ComputeResidualFixedStencil { @@ -109,6 +154,13 @@ public: typedef GhostLayerField< real_t, 1 > Field_T; typedef std::vector< real_t > Weight_T; + //******************************************************************************************************************* + /* \param blocks the block storage where the fields are stored + * \param uId the block data id of the solution field + * \param fId the block data id of the right-hand side field + * \param weights vector of stencil weights for the discrete operator + * \param rId the block data id of the residual field + *******************************************************************************************************************/ ComputeResidualFixedStencil( const shared_ptr< domain_decomposition::StructuredBlockStorage > & blocks, const BlockDataID & uId, const BlockDataID & fId, const std::vector <real_t> & weights, const BlockDataID & rId ) : blocks_( blocks ), uId_( uId ), fId_( fId ), weights_( weights ), rId_( rId ) @@ -127,12 +179,21 @@ private: +//********************************************************************************************************************** +/*! + * \brief Sweep that sets all values in a field to zero + */ +//********************************************************************************************************************** class Zeroize { public: typedef GhostLayerField< real_t, 1 > Field_T; + //******************************************************************************************************************* + /* \param blocks the block storage where the field is stored + * \param fieldId the block data id of the field + *******************************************************************************************************************/ Zeroize( const shared_ptr< domain_decomposition::StructuredBlockStorage > & blocks, const BlockDataID & fieldId ) : blocks_( blocks ), fieldId_( fieldId ) { } @@ -150,6 +211,97 @@ private: +//********************************************************************************************************************** +/*! + * \brief Direct Coarsening Approach for the stencil field + * + * \tparam Stencil_T The stencil used for the discrete operator + */ +//********************************************************************************************************************** +template< typename Stencil_T > +class CoarsenStencilFieldsDCA +{ +public: + + typedef GhostLayerField< real_t, Stencil_T::Size > StencilField_T; + + //******************************************************************************************************************* + /* \param blocks the block storage where the fields are stored + * \param numLvl number of grid levels to use (including the finest level) + * \param operatorOrder the order of the (continuum) differential operator, e.g. 2 for Laplace + *******************************************************************************************************************/ + CoarsenStencilFieldsDCA( shared_ptr< StructuredBlockForest > blocks, + const uint_t numLvl, const uint_t operatorOrder, + const Set<SUID> & requiredSelectors = Set<SUID>::emptySet(), + const Set<SUID> & incompatibleSelectors = Set<SUID>::emptySet() ) + : blocks_( blocks ), numLvl_(numLvl), operatorOrder_(operatorOrder), + requiredSelectors_( requiredSelectors ), incompatibleSelectors_( incompatibleSelectors ) + { } + + //******************************************************************************************************************* + /* \param stencilFieldId a vector of the block data ids of the stencil field for all levels (finest first) + *******************************************************************************************************************/ + void operator()(const std::vector<BlockDataID> & stencilFieldId) const; + +private: + + shared_ptr< domain_decomposition::StructuredBlockStorage > blocks_; + + uint_t numLvl_; + uint_t operatorOrder_; + + Set< SUID > requiredSelectors_; + Set< SUID > incompatibleSelectors_; + +}; + + + +//********************************************************************************************************************** +/*! + * \brief Galerkin Coarsening Approach for the stencil field + * + * \tparam Stencil_T The stencil used for the discrete operator + */ +//********************************************************************************************************************** +template< typename Stencil_T > +class CoarsenStencilFieldsGCA +{ +public: + + typedef GhostLayerField< real_t, Stencil_T::Size > StencilField_T; + + //******************************************************************************************************************* + /* \param blocks the block storage where the fields are stored + * \param numLvl number of grid levels to use (including the finest level) + * \param overrelaxFact overrelaxation factor, e.g. 2 for the Poisson equation + *******************************************************************************************************************/ + CoarsenStencilFieldsGCA( shared_ptr< StructuredBlockForest > blocks, + const uint_t numLvl, const real_t overrelaxFact = real_t(1), + const Set<SUID> & requiredSelectors = Set<SUID>::emptySet(), + const Set<SUID> & incompatibleSelectors = Set<SUID>::emptySet() ) + : blocks_( blocks ), numLvl_(numLvl), overrelaxFact_(overrelaxFact), + requiredSelectors_( requiredSelectors ), incompatibleSelectors_( incompatibleSelectors ) + { } + + //******************************************************************************************************************* + /* \param stencilFieldId a vector of the block data ids of the stencil field for all levels (finest first) + *******************************************************************************************************************/ + void operator()(const std::vector<BlockDataID> & stencilFieldId) const; + +private: + + shared_ptr< domain_decomposition::StructuredBlockStorage > blocks_; + + uint_t numLvl_; + real_t overrelaxFact_; + + Set< SUID > requiredSelectors_; + Set< SUID > incompatibleSelectors_; + +}; + + } // namespace pde } // namespace walberla diff --git a/src/pde/sweeps/Multigrid.impl.h b/src/pde/sweeps/Multigrid.impl.h index e83cf18b7f1ff496cefcf0496c62a42896f221a6..e4b5decf62bcd597fc7ef11eea707d1b3f85f42a 100644 --- a/src/pde/sweeps/Multigrid.impl.h +++ b/src/pde/sweeps/Multigrid.impl.h @@ -24,6 +24,19 @@ #include "Multigrid.h" +#include "stencil/D3Q7.h" + +#ifdef _MSC_VER +# pragma warning(push) +// disable warning for multi_array: "declaration of 'extents' hides global declaration" +# pragma warning( disable : 4459 ) +#endif //_MSC_VER + +#include <boost/multi_array.hpp> + +#ifdef _MSC_VER +# pragma warning(pop) +#endif //_MSC_VER namespace walberla { @@ -53,6 +66,7 @@ void Restrict< Stencil_T >::operator()( IBlock * const block ) const else { WALBERLA_ASSERT_EQUAL(z, 0); + coarse->get(x,y,z) = real_t(0); } coarse->get(x,y,z) += fine->get(fx , fy , fz ) + fine->get(fx+1, fy , fz ) @@ -140,5 +154,120 @@ void ComputeResidualFixedStencil< Stencil_T >::operator()( IBlock * const block +template< typename Stencil_T > +void CoarsenStencilFieldsDCA<Stencil_T >::operator()( const std::vector<BlockDataID> & stencilFieldId ) const +{ + const real_t scalingFactor = real_t(1)/real_c(2<< (operatorOrder_-1) ); // scaling by ( 1/h^operatorOrder )^lvl + + WALBERLA_ASSERT_EQUAL(numLvl_, stencilFieldId.size(), "This function can only be called when operating with stencil fields!"); + + for ( uint_t lvl = 1; lvl < numLvl_; ++lvl ) + { + for( auto block = blocks_->begin( requiredSelectors_, incompatibleSelectors_ ); block != blocks_->end(); ++block ) + { + StencilField_T * fine = block->template getData< StencilField_T >( stencilFieldId[lvl-1] ); + StencilField_T * coarse = block->template getData< StencilField_T >( stencilFieldId[lvl] ); + + WALBERLA_FOR_ALL_CELLS_XYZ(coarse, + for( auto dir = Stencil_T::begin(); dir != Stencil_T::end(); ++dir ) + coarse->get(x,y,z, dir.toIdx()) = scalingFactor * fine->get(x,y,z, dir.toIdx()); + ) + } + } +} + + + +template< > +void CoarsenStencilFieldsGCA< stencil::D3Q7 >::operator()( const std::vector<BlockDataID> & stencilFieldId ) const +{ + + WALBERLA_ASSERT_EQUAL(numLvl_, stencilFieldId.size(), "This function can only be called when operating with stencil fields!"); + + // Apply Galerkin coarsening to each level // + // currently only implemented for CCMG with constant restriction and prolongation + + for ( uint_t lvl = 1; lvl < numLvl_; ++lvl ) + { + for( auto block = blocks_->begin( requiredSelectors_, incompatibleSelectors_ ); block != blocks_->end(); ++block ) + { + StencilField_T * fine = block->getData< StencilField_T >( stencilFieldId[lvl-1] ); + StencilField_T * coarse = block->getData< StencilField_T >( stencilFieldId[lvl] ); + + + typedef boost::multi_array<real_t, 3> Array3D; + Array3D p(boost::extents[7][7][7]); + Array3D r(boost::extents[2][2][2]); + + // Set to restriction weights from constant restrict operator + for(Array3D::index z=0; z<2; ++z) { + for(Array3D::index y=0; y<2; ++y) { + for(Array3D::index x=0; x<2; ++x) { + r[x][y][z] = real_t(1); + } + } + } + + // Init to 0 // + for(Array3D::index k=0; k<7; ++k) { + for(Array3D::index j=0; j<7; ++j) { + for(Array3D::index i=0; i<7; ++i) { + p[i][j][k] = real_t(0); + } + } + } + + // Set center to prolongation weights, including overrelaxation factor (latter therefore no longer needed in ProlongateAndCorrect) + for(Array3D::index k=0; k<2; ++k) { + for(Array3D::index j=0; j<2; ++j) { + for(Array3D::index i=0; i<2; ++i) { + p[i+2][j+2][k+2] = real_t(0.125)/overrelaxFact_; // Factor 0.125 such that same prolongation operator for DCA and GCA + } + } + } + + + WALBERLA_FOR_ALL_CELLS_XYZ(coarse, + + Array3D ap(boost::extents[7][7][7]); + + const cell_idx_t fx = 2*x; + const cell_idx_t fy = 2*y; + const cell_idx_t fz = 2*z; + + for(Array3D::index k=0; k<7; ++k) + for(Array3D::index j=0; j<7; ++j) + for(Array3D::index i=0; i<7; ++i) + ap[i][j][k] = real_t(0); + + + // Tested for spatially varying stencils! // + for(Array3D::index k=1; k<5; ++k) + for(Array3D::index j=1; j<5; ++j) + for(Array3D::index i=1; i<5; ++i) { + ap[i][j][k] = real_t(0); + for(auto d = stencil::D3Q7::begin(); d != stencil::D3Q7::end(); ++d ){ + ap[i][j][k] += p[ i+d.cx() ] [ j+d.cy() ] [k+d.cz() ] * fine->get( fx+cell_idx_c(i%2), fy+cell_idx_c(j%2), fz+cell_idx_c(k%2), d.toIdx() ); // contains elements of one row of coarse grid matrix + } + } + + // Checked, correct! // + for(auto d = stencil::D3Q7::begin(); d != stencil::D3Q7::end(); ++d ){ + real_t sum = 0; + for(Array3D::index k=0; k<2; ++k) + for(Array3D::index j=0; j<2; ++j) + for(Array3D::index i=0; i<2; ++i) { + sum += ap[i+2-2*d.cx()] [j+2-2*d.cy()] [k+2-2*d.cz()] * r[i][j][k]; + // either i+0 or i+4 // either j+0 or j+4 // either k+0 or k+4 // always 1 here + } + + coarse->get(x,y,z,*d) = sum; + } + ) + } + } +} + + } // namespace pde } // namespace walberla diff --git a/src/pde/sweeps/RBGS.h b/src/pde/sweeps/RBGS.h index 1f3404341379aea84ab26e4d514a8a5f9cc9ff58..69f7245fac91a5e77ec5bdddb2b25fa92d45d253 100644 --- a/src/pde/sweeps/RBGS.h +++ b/src/pde/sweeps/RBGS.h @@ -26,7 +26,7 @@ #include "stencil/Directions.h" #include <map> - +#include <functional> namespace walberla { @@ -53,12 +53,12 @@ public: std::function< void ( IBlock * const ) > getRedSweep() { - return boost::bind( &RBGS::update, this, _1, true ); + return std::bind( &RBGS::update, this, std::placeholders::_1, true ); } std::function< void ( IBlock * const ) > getBlackSweep() { - return boost::bind( &RBGS::update, this, _1, false ); + return std::bind( &RBGS::update, this, std::placeholders::_1, false ); } private: diff --git a/src/pde/sweeps/RBGSFixedStencil.h b/src/pde/sweeps/RBGSFixedStencil.h index 76df0005548e9df4126d30e017ce10bb1d75f750..75196987f18a941a716661f95873c8c960276904 100644 --- a/src/pde/sweeps/RBGSFixedStencil.h +++ b/src/pde/sweeps/RBGSFixedStencil.h @@ -26,7 +26,7 @@ #include "stencil/Directions.h" #include <map> - +#include <functional> namespace walberla { @@ -52,12 +52,12 @@ public: std::function< void ( IBlock * const ) > getRedSweep() { - return boost::bind( &RBGSFixedStencil::update, this, _1, true ); + return std::bind( &RBGSFixedStencil::update, this, std::placeholders::_1, true ); } std::function< void ( IBlock * const ) > getBlackSweep() { - return boost::bind( &RBGSFixedStencil::update, this, _1, false ); + return std::bind( &RBGSFixedStencil::update, this, std::placeholders::_1, false ); } private: diff --git a/src/pde/sweeps/SOR.h b/src/pde/sweeps/SOR.h index 90be98268340223cd6e22d750c7db6bee9d5105b..4997b40d6af610f7e995ae7229339dbb08e97b93 100644 --- a/src/pde/sweeps/SOR.h +++ b/src/pde/sweeps/SOR.h @@ -26,7 +26,7 @@ #include "stencil/Directions.h" #include <map> - +#include <functional> namespace walberla { @@ -53,12 +53,12 @@ public: std::function< void ( IBlock * const ) > getRedSweep() { - return boost::bind( &SOR::update, this, _1, true ); + return std::bind( &SOR::update, this, std::placeholders::_1, true ); } std::function< void ( IBlock * const ) > getBlackSweep() { - return boost::bind( &SOR::update, this, _1, false ); + return std::bind( &SOR::update, this, std::placeholders::_1, false ); } private: diff --git a/src/pde/sweeps/SORFixedStencil.h b/src/pde/sweeps/SORFixedStencil.h index 51535e0378b9ccaa5bcf1181442ed5ff7bdba5ec..d3983ab1861c856c388d7c2feb3601c654f0e58f 100644 --- a/src/pde/sweeps/SORFixedStencil.h +++ b/src/pde/sweeps/SORFixedStencil.h @@ -26,7 +26,7 @@ #include "stencil/Directions.h" #include <map> - +#include <functional> namespace walberla { @@ -52,12 +52,12 @@ public: std::function< void ( IBlock * const ) > getRedSweep() { - return boost::bind( &SORFixedStencil::update, this, _1, true ); + return std::bind( &SORFixedStencil::update, this, std::placeholders::_1, true ); } std::function< void ( IBlock * const ) > getBlackSweep() { - return boost::bind( &SORFixedStencil::update, this, _1, false ); + return std::bind( &SORFixedStencil::update, this, std::placeholders::_1, false ); } private: diff --git a/src/pe/CMakeLists.txt b/src/pe/CMakeLists.txt index 1dd7edd80c06535b2df4798075355d75fa46cd90..dadbb9186bda2e10b45607705aa606da413a0ce0 100644 --- a/src/pe/CMakeLists.txt +++ b/src/pe/CMakeLists.txt @@ -5,27 +5,4 @@ # ################################################################################################### -if(WALBERLA_DOUBLE_ACCURACY) - set(CCD_DOUBLE ON) - set(CCD_SINGLE OFF) -else() - set(CCD_DOUBLE OFF) - set(CCD_SINGLE ON) -endif() - -configure_file(extern/libccd/ccd/config.h.cmake.in extern/libccd/ccd/config.h) - -include_directories(extern/libccd) -include_directories("${CMAKE_CURRENT_BINARY_DIR}/extern/libccd") - waLBerla_add_module( DEPENDS core blockforest domain_decomposition geometry stencil vtk ) - -if( WALBERLA_CXX_COMPILER_IS_MSVC ) - SET_SOURCE_FILES_PROPERTIES( extern/libccd/ccd.c - extern/libccd/mpr.c - extern/libccd/polytope.c - extern/libccd/support.c - extern/libccd/vec3.c - PROPERTIES LANGUAGE CXX ) -endif() - diff --git a/src/pe/Types.h b/src/pe/Types.h index 764bf4bb70610b43ec54215b60c85a95219ae25f..c71ee80907fa5506206c58de904e21d2bebc4550 100644 --- a/src/pe/Types.h +++ b/src/pe/Types.h @@ -27,6 +27,7 @@ #include <boost/array.hpp> +#include <memory> #include <vector> namespace walberla{ @@ -57,8 +58,6 @@ using math::AABB; // //================================================================================================= -class Attachable; -class BallJoint; class BodyManager; class BodyStorage; class Box; @@ -67,21 +66,11 @@ class Contact; class Cylinder; class Ellipsoid; class CylindricalBoundary; -class FixedJoint; -class ForceGenerator; class GeomPrimitive; -class Gravity; -class HingeJoint; -class Joint; -class Link; class Material; class MPISystem; -class Node; class Plane; -class Process; class RigidBody; -class Section; -class SliderJoint; class Sphere; class Spring; class Squirmer; @@ -92,6 +81,7 @@ class Union; typedef RigidBody BodyType; //!< Type of the rigid bodies. typedef RigidBody* BodyID; //!< Handle for a rigid body. typedef const RigidBody* ConstBodyID; //!< Handle for a constant rigid body. +using BodyPtr = std::unique_ptr<RigidBody>; typedef GeomPrimitive* GeomID; typedef const GeomPrimitive* ConstGeomID; @@ -99,80 +89,52 @@ typedef const GeomPrimitive* ConstGeomID; typedef Box BoxType; //!< Type of the box geometric primitive. typedef Box* BoxID; //!< Handle for a box primitive. typedef const Box* ConstBoxID; //!< Handle for a constant box primitive. +using BoxPtr = std::unique_ptr<Box>; typedef Capsule CapsuleType; //!< Type of the capsule geometric primitive. typedef Capsule* CapsuleID; //!< Handle for a capsule primitive. typedef const Capsule* ConstCapsuleID; //!< Handle for a constant capsule primitive. +using CapsulePtr = std::unique_ptr<Capsule>; typedef Cylinder CylinderType; //!< Type of the cylinder geometric primitive. typedef Cylinder* CylinderID; //!< Handle for a cylinder primitive. typedef const Cylinder* ConstCylinderID; //!< Handle for a constant cylinder primitive. +using CylinderPtr = std::unique_ptr<Cylinder>; typedef CylindricalBoundary CylindricalBoundaryType; //!< Type of the cylindrical boundary geometric primitive. typedef CylindricalBoundary* CylindricalBoundaryID; //!< Handle for a cylindrical boundary primitive. typedef const CylindricalBoundary* ConstCylindricalBoundaryID; //!< Handle for a constant cylindrical boundary primitive. +using CylindricalBoundaryPtr = std::unique_ptr<CylindricalBoundary>; typedef Ellipsoid EllipsoidType; //!< Type of the ellipsoid geometric primitive. typedef Ellipsoid* EllipsoidID; //!< Handle for a ellipsoid primitive. typedef const Ellipsoid* ConstEllipsoidID; //!< Handle for a constant ellipsoid primitive. +using EllipsoidPtr = std::unique_ptr<Ellipsoid>; typedef Plane PlaneType; //!< Type of the plane geometric primitive. typedef Plane* PlaneID; //!< Handle for a plane primitive. typedef const Plane* ConstPlaneID; //!< Handle for a constant plane primitive. +using PlanePtr = std::unique_ptr<Plane>; typedef Sphere SphereType; //!< Type of the sphere geometric primitive. typedef Sphere* SphereID; //!< Handle for a sphere primitive. typedef const Sphere* ConstSphereID; //!< Handle for a constant sphere primitive. +using SpherePtr = std::unique_ptr<Sphere>; typedef Squirmer SquirmerType; //!< Type of the squirmer geometric primitive. typedef Squirmer* SquirmerID; //!< Handle for a squirmer primitive. typedef const Squirmer* ConstSquirmerID; //!< Handle for a constant squirmer primitive. +using SquirmerPtr = std::unique_ptr<Squirmer>; typedef TriangleMesh MeshType; //!< Type of the triangle mesh geometric primitive. typedef TriangleMesh* MeshID; //!< Handle for a triangle mesh primitive. typedef const TriangleMesh* ConstMeshID; //!< Handle for a constant triangle mesh primitive. - -typedef Attachable AttachableType; //!< Type of the attachables. -typedef Attachable* AttachableID; //!< Handle for an attachable. -typedef const Attachable* ConstAttachableID; //!< Handle for a constant attachable. - -typedef Gravity GravityType; //!< Type of the gravity force generators. -typedef Gravity* GravityID; //!< Handle for a gravity force generator. -typedef const Gravity* ConstGravityID; //!< Handle for a constant gravity force generator. - -typedef Spring SpringType; //!< Type of the spring force generators. -typedef Spring* SpringID; //!< Handle for a spring force generator. -typedef const Spring* ConstSpringID; //!< Handle for a constant spring force generator. +using TriangleMeshPtr = std::unique_ptr<TriangleMesh>; typedef Contact ContactType; //!< Type of the contacts. typedef Contact* ContactID; //!< Handle for a contact. typedef const Contact* ConstContactID; //!< Handle for a constant contact. -typedef Joint JointType; //!< Type of the joints. -typedef Joint* JointID; //!< Handle for a joint. -typedef const Joint* ConstJointID; //!< Handle for a constant joint. - -typedef SliderJoint SliderJointType; //!< Type of the slider joint. -typedef SliderJoint* SldierJointID; //!< Handle for a slider joint. -typedef const SliderJoint* ConstSliderJointID; //!< Handle for a constant slider joint. - -typedef HingeJoint HingeJointType; //!< Type of the hinge joint. -typedef HingeJoint* HingeJointID; //!< Handle for a hinge joint. -typedef const HingeJoint* ConstHingeJointID; //!< Handle for a constant hinge joint. - -typedef BallJoint BallJointType; //!< Type of the ball joint. -typedef BallJoint* BallJointID; //!< Handle for a ball joint. -typedef const BallJoint* ConstBallJointID; //!< Handle for a constant ball joint. - -typedef Node NodeType; -typedef Node* NodeID; //!< Handle to a BodyTrait instance. -typedef const Node* ConstNodeID; //!< Handle to a constant BodyTrait instance. - -typedef Process ProcessType; //!< Type of the remote processes. -typedef Process* ProcessID; //!< Handle for a remote process. -typedef const Process* ConstProcessID; //!< Handle for a constant remote process. - - typedef BodyManager* ManagerID; //!< Handle for a BodyManager. typedef const BodyManager* ConstManagerID; //!< Handle for a constant BodyManager. diff --git a/src/pe/amr/weight_assignment/MetisAssignmentFunctor.h b/src/pe/amr/weight_assignment/MetisAssignmentFunctor.h index 720c80a2e363302f6b60a582c7628000cada10ea..dd1fdac59c24ae7d751fc9014236109ccaedfca3 100644 --- a/src/pe/amr/weight_assignment/MetisAssignmentFunctor.h +++ b/src/pe/amr/weight_assignment/MetisAssignmentFunctor.h @@ -23,6 +23,7 @@ #include "pe/amr/InfoCollection.h" #include "blockforest/loadbalancing/DynamicParMetis.h" +#include "domain_decomposition/PeriodicIntersectionVolume.h" namespace walberla { namespace pe { @@ -37,36 +38,50 @@ public: MetisAssignmentFunctor( shared_ptr<InfoCollection>& ic, const real_t baseWeight = real_t(10.0) ) : ic_(ic), baseWeight_(baseWeight) {} - void operator()( std::vector< std::pair< const PhantomBlock *, walberla::any > > & blockData, const PhantomBlockForest & ) + void operator()( std::vector< std::pair< const PhantomBlock *, walberla::any > > & blockData, const PhantomBlockForest & forest ) { + const std::array< bool, 3 > periodic {{forest.getBlockForest().isPeriodic(0), + forest.getBlockForest().isPeriodic(1), + forest.getBlockForest().isPeriodic(2)}}; + const math::AABB domain = forest.getBlockForest().getDomain(); + for( auto it = blockData.begin(); it != blockData.end(); ++it ) { - const double weight = double_c( ic_->find( it->first->getId() )->second.numberOfLocalBodies ) + baseWeight_; - //const double commWeight = double_c( edgeWeightFactor * (double_c(ic_->find( it->first->getId() )->second.numberOfShadowBodies) + baseWeight_)) + 1; + const PhantomBlock * block = it->first; + //only change of one level is supported! + WALBERLA_ASSERT_LESS( abs(int_c(block->getLevel()) - int_c(block->getSourceLevel())), 2 ); + + //all information is provided by info collection + auto infoIt = ic_->find( block->getId() ); + WALBERLA_CHECK_UNEQUAL( infoIt, ic_->end() ); + const double weight = double_c( infoIt->second.numberOfLocalBodies ) + baseWeight_; blockforest::DynamicParMetisBlockInfo info( 0 ); info.setVertexWeight( int64_c(weight) ); info.setVertexSize( int64_c( weight ) ); info.setVertexCoords( it->first->getAABB().center() ); for( uint_t nb = uint_t(0); nb < it->first->getNeighborhoodSize(); ++nb ) { - info.setEdgeWeight(it->first->getNeighborId(nb), int64_c(edgeWeight_) ); + const double dx(1.0); + info.setEdgeWeight( it->first->getNeighborId(nb), + static_cast<blockforest::DynamicParMetisBlockInfo::weight_t>( + domain_decomposition::periodicIntersectionVolume( periodic, + domain, + it->first->getAABB(), + it->first->getNeighborAABB(nb).getExtended(dx))) ); } it->second = info; + continue; } } inline void setBaseWeight( const double weight) { baseWeight_ = weight;} inline double getBaseWeight() const { return baseWeight_; } - inline void setEdgeWeight( const double weight) { edgeWeight_ = weight;} - inline double getEdgeWeight() const { return edgeWeight_; } - private: shared_ptr< InfoCollection > ic_; ///Base weight due to allocated data structures. A weight of zero for blocks is dangerous as empty blocks might accumulate on one process! double baseWeight_ = 10.0; - double edgeWeight_ = 1.0; }; } diff --git a/src/pe/amr/weight_assignment/WeightAssignmentFunctor.h b/src/pe/amr/weight_assignment/WeightAssignmentFunctor.h index 1632bc596e1c3b01fc9d090e5fd29ca6c1f18ad0..7c7b381786967bd739b31f6c49ed673230ebd4fb 100644 --- a/src/pe/amr/weight_assignment/WeightAssignmentFunctor.h +++ b/src/pe/amr/weight_assignment/WeightAssignmentFunctor.h @@ -43,37 +43,11 @@ public: { const PhantomBlock * block = it->first; //only change of one level is supported! - WALBERLA_ASSERT_LESS( int_c(block->getLevel()) - int_c(block->getSourceLevel()), 2 ); + WALBERLA_CHECK_LESS( abs(int_c(block->getLevel()) - int_c(block->getSourceLevel())), 2 ); - if (block->sourceBlockIsLarger()) - { - auto infoIt = ic_->find( block->getId()/*.getFatherId()*/ ); - WALBERLA_ASSERT_UNEQUAL( infoIt, ic_->end() ); - it->second = PhantomBlockWeight( double_c(infoIt->second.numberOfLocalBodies) + baseWeight_ ); - continue; - } - - if (block->sourceBlockHasTheSameSize()) - { - auto infoIt = ic_->find( block->getId() ); - WALBERLA_ASSERT_UNEQUAL( infoIt, ic_->end() ); - it->second = PhantomBlockWeight( double_c(infoIt->second.numberOfLocalBodies) + baseWeight_ ); - continue; - } - - if (block->sourceBlockIsSmaller()) - { - double weight = 0; - for (uint_t child = 0; child < 8; ++child) - { - blockforest::BlockID childId(block->getId(), child); - auto childIt = ic_->find( childId ); - WALBERLA_ASSERT_UNEQUAL( childIt, ic_->end() ); - weight += double_c(childIt->second.numberOfLocalBodies); - } - it->second = PhantomBlockWeight( weight + baseWeight_ ); - continue; - } + auto infoIt = ic_->find( block->getId()/*.getFatherId()*/ ); + WALBERLA_CHECK_UNEQUAL( infoIt, ic_->end() ); + it->second = PhantomBlockWeight( double_c(infoIt->second.numberOfLocalBodies) + baseWeight_ ); } } diff --git a/src/pe/attachable/Attachable.cpp b/src/pe/attachable/Attachable.cpp deleted file mode 100644 index 76056d6866479db8625431b72e49b7c87bcc06f8..0000000000000000000000000000000000000000 --- a/src/pe/attachable/Attachable.cpp +++ /dev/null @@ -1,143 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file Attachable.cpp -//! \author Klaus Iglberger -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -//! \brief Source file for the Attachable class -// -//====================================================================================================================== - - -//************************************************************************************************* -// Includes -//************************************************************************************************* - -#include <pe/attachable/Attachable.h> -#include <pe/attachable/AttachableStorage.h> -#include <core/DataTypes.h> - -namespace walberla { -namespace pe { - -//================================================================================================= -// -// CONSTRUCTOR -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Constructor of the Attachable class. - * - * \param type The type of the rigid body. - * \param sid The unique system-specific ID of the attachable. - */ -Attachable::Attachable( AttachableType type, id_t sid ) - : type_(type) - , sid_(sid) - , bodies_() -{} -//************************************************************************************************* - - - - -//================================================================================================= -// -// DESTRUCTOR -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Destructor for the Attachable class. - */ -Attachable::~Attachable() -{ -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// MPI FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\fn bool Attachable::isRemote() const - * \brief Returns whether the attachable is remote or not. - * - * \return \a true in case the attachable is remote, \a false if not. - * - * This function returns whether the attachable is remote or not. In case the attachable is - * attached to at least a single local rigid body the function returns \a false. Otherwise - * it returns \a true. - */ -//************************************************************************************************* - - - - -//================================================================================================= -// -// ATTACHABLE SETUP FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Detaches the given attachable. - * - * \param attachable The detachable to be detached. - */ -WALBERLA_PUBLIC void detach( AttachableID attachable ) -{ - ///TDOD REVIEW -// typedef AttachableStorage AS; - - // WARNING: Using friend relationship to get non-constant reference of attachable storage. -// AS& attachablestorage( theCollisionSystem()->attachablestorage_ ); - - // Removing the attachable from the attachable storage -// const AS::Iterator pos( attachablestorage.find( attachable ) ); -// attachablestorage.remove( pos ); - - delete attachable; -} -//************************************************************************************************* - -//************************************************************************************************* -/*!\brief Global output operator for AttachableType. - * - * \param os Reference to the output stream. - * \param type The AttachableType to be put into the stream. - * \return Reference to the output stream. - */ -std::ostream& operator<<( std::ostream& os, Attachable::AttachableType type ) -{ - switch( type ) - { - case Attachable::gravityType: os << "gravity force generator"; break; - case Attachable::springType: os << "spring force generator"; break; - default: WALBERLA_ASSERT( false, "Unknown attachable type" ); break; - } - - return os; -} -//************************************************************************************************* - -} // namespace pe -} // namespace walberla diff --git a/src/pe/attachable/Attachable.h b/src/pe/attachable/Attachable.h deleted file mode 100644 index 9c7b2b368ad9d0377cd3284be39132122cfeb752..0000000000000000000000000000000000000000 --- a/src/pe/attachable/Attachable.h +++ /dev/null @@ -1,264 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file Attachable.h -//! \author Klaus Iglberger -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -//! \brief Header file for the Attachable class -// -//====================================================================================================================== - -#pragma once - - -//************************************************************************************************* -// Includes -//************************************************************************************************* - -#include <core/NonCopyable.h> -#include <pe/Types.h> -#include <core/ptrvector/policies/NoDelete.h> -#include <core/ptrvector/PtrVector.h> -#include <pe/Types.h> - -#include "core/UniqueID.h" - -namespace walberla { -namespace pe { - -//================================================================================================= -// -// CLASS DEFINITION -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Attachable interface class. - * - * The Attachable class is the base class for the Attachable concept of the physics engine. - * Classes deriving from this interface class (which are simply called Attachables) can be - * attached to rigid bodies and are notified in case the rigid body is destroyed. This - * concept is for example used for all force generators (see the ForceGenerator class - * description). - */ -class Attachable : private NonCopyable -{ -public: - //************************************************************************************************* - //! Type codes of the attachables. - enum AttachableType { - gravityType = 1, //!< Code for the Gravity force generator. - springType = 2 //!< Code for the Spring force generator. - }; - //************************************************************************************************* -protected: - //**Type definitions**************************************************************************** - typedef PtrVector<RigidBody,NoDelete> Bodies; //!< Vector for attached rigid bodies. - //********************************************************************************************** - - //**Constructor********************************************************************************* - /*!\name Constructor */ - //@{ - explicit Attachable( AttachableType type, id_t sid ); - //@} - //********************************************************************************************** - - //**Destructor********************************************************************************** - /*!\name Destructor */ - //@{ - virtual ~Attachable(); - //@} - //********************************************************************************************** - -public: - - //**Type definitions**************************************************************************** - typedef Bodies::Iterator Iterator; //!< Iterator over the currently attached bodies. - typedef Bodies::ConstIterator ConstIterator; //!< ConstIterator over the currently attached bodies. - //********************************************************************************************** - - //**MPI functions******************************************************************************* - /*!\name MPI functions */ - //@{ - virtual bool isRemote() const = 0; - //@} - //********************************************************************************************** - - //**Get functions******************************************************************************* - /*!\name Get functions */ - //@{ - inline AttachableType getType() const; - inline id_t getSystemID() const; - //@} - //********************************************************************************************** - - //**Utility functions*************************************************************************** - /*!\name Utility functions */ - //@{ - inline Iterator begin(); - inline ConstIterator begin() const; - inline Iterator end (); - inline ConstIterator end () const; - inline size_t size () const; - //@} - //********************************************************************************************** - -protected: - //**Member variables**************************************************************************** - /*!\name Member variables */ - //@{ - const AttachableType type_; //!< The type code of the attachable. - id_t sid_; //!< The unique system-specific attachable ID. - Bodies bodies_; //!< Vector of attached rigid bodies. - //@} - //********************************************************************************************** - -private: - //**Attachable setup functions****************************************************************** - /*! \cond internal */ - friend void detach( AttachableID attachable ); - /*! \endcond */ - //********************************************************************************************** -}; -//************************************************************************************************* - - - - -//================================================================================================= -// -// ATTACHABLE SETUP FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\name Attachable setup functions */ -//@{ -void detach( AttachableID attachable ); -//@} -//************************************************************************************************* - -//================================================================================================= -// -// GET FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Returns the type of the attachable. - * - * \return The type of the attachable. - */ -inline Attachable::AttachableType Attachable::getType() const -{ - return type_; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns the unique system-specific ID of the attachable. - * - * \return The system-specific ID. - */ -inline id_t Attachable::getSystemID() const -{ - return sid_; -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// UTILITY FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Returns an iterator to the first attached rigid body. - * - * \return Iterator to the first attached rigid body. - */ -inline Attachable::Iterator Attachable::begin() -{ - return bodies_.begin(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator to the first attached rigid body. - * - * \return Iterator to the first attached rigid body. - */ -inline Attachable::ConstIterator Attachable::begin() const -{ - return bodies_.begin(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator just past the last attached rigid body. - * - * \return Iterator just past the last attached rigid body. - */ -inline Attachable::Iterator Attachable::end() -{ - return bodies_.end(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator just past the last attached rigid body. - * - * \return Iterator just past the last attached rigid body. - */ -inline Attachable::ConstIterator Attachable::end() const -{ - return bodies_.end(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns the number of attached rigid bodies. - * - * \return The number of attached rigid bodies - */ -inline size_t Attachable::size() const -{ - return bodies_.size(); -} -//************************************************************************************************* - -//================================================================================================= -// -// ATTACHABLE TYPE UTILITY FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\name Attachable type utility functions */ -//@{ -std::ostream& operator<<( std::ostream& os, Attachable::AttachableType type ); -//@} -//************************************************************************************************* - -} // namespace pe -} // namespace walberla diff --git a/src/pe/attachable/AttachableCast.h b/src/pe/attachable/AttachableCast.h deleted file mode 100644 index bace6db7f1aa632f16c9d70de8f8ede1f8ffcd49..0000000000000000000000000000000000000000 --- a/src/pe/attachable/AttachableCast.h +++ /dev/null @@ -1,93 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file AttachableCast.h -//! \author Klaus Iglberger -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -// -//====================================================================================================================== - -#pragma once - -#include <boost/type_traits/is_base_of.hpp> - -namespace walberla { -namespace pe { - -//================================================================================================= -// -// ATTACHABLE CAST OPERATORS -// -//================================================================================================= - -//************************************************************************************************* -/*!\name Attachable cast operators */ -//@{ -template< typename To, typename From > inline To* static_attachable_cast( From* attachable ); -template< typename To, typename From > inline To* dynamic_attachable_cast( From* attachable ); -//@} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Static cast for attachables. - * - * \param attachable The attachable to be cast. - * \return The casted attachable. - * - * The static_attachable_cast function is used exactly as the built-in static_cast operator - * but for attachables. - - \code - SphereID sphere = createSphere ( 1, 0.0, 0.0, 0.0, 1.0, iron ); - AttachableID attachable = attachGravity( sphere, 0.0, 0.0, -9.81 ); - GravityID gravity = static_attachable_cast<Gravity>( attachable ); - \endcode - */ -template< typename To, typename From > -inline To* static_attachable_cast( From* attachable ) -{ - static_assert(boost::is_base_of<Attachable, From>::value, "From has to be derived from Attachable!"); - static_assert(boost::is_base_of<Attachable, To>::value, "To has to be derived from Attachable!"); - return static_cast<To*>( attachable ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Dynamic cast for attachables. - * - * \param attachable The attachable to be cast. - * \return The casted attachable. - * - * The dynamic_attachable_cast function is used exactly as the built-in dynamic_cast operator - * but for attachables. - - \code - AttachableID attachable; - GravityID gravity = dynamic_attachable_cast<Gravity>( attachable ); - \endcode - */ -template< typename To, typename From > -inline To* dynamic_attachable_cast( From* attachable ) -{ - static_assert(boost::is_base_of<Attachable, From>::value, "From has to be derived from Attachable!"); - static_assert(boost::is_base_of<Attachable, To>::value, "To has to be derived from Attachable!"); - return dynamic_cast<To*>( attachable ); -} -//************************************************************************************************* - -} // namespace pe -} diff --git a/src/pe/attachable/AttachableStorage.h b/src/pe/attachable/AttachableStorage.h deleted file mode 100644 index 009c3b087bef8d6556e071306846d210b548dd90..0000000000000000000000000000000000000000 --- a/src/pe/attachable/AttachableStorage.h +++ /dev/null @@ -1,356 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file AttachableStorage.h -//! \author Klaus Iglberger -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -// -//====================================================================================================================== - -#pragma once - - -//************************************************************************************************* -// Includes -//************************************************************************************************* - -#include <algorithm> -#include <functional> -#include <pe/attachable/Attachable.h> -#include <pe/Types.h> -#include <core/ptrvector/policies/NoDelete.h> -#include <core/ptrvector/PtrVector.h> -#include <core/DataTypes.h> -#include <core/debug/Debug.h> - -namespace walberla { -namespace pe { - -//================================================================================================= -// -// CLASS DEFINITION -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Attachable storage of the rigid body simulation world. - * - * The AttachableStorage class stores all currently existing attachables in the simulation world - * (see class World). - */ -class AttachableStorage -{ -private: - //**Type definitions**************************************************************************** - //! Container for the attachables contained in the simulation world. - typedef PtrVector<Attachable,NoDelete> Attachables; - //********************************************************************************************** - -public: - //**Type definitions**************************************************************************** - typedef Attachables::SizeType SizeType; //!< Size type of the attachable storage. - typedef Attachables::Iterator Iterator; //!< Iterator over non-const attachables. - typedef Attachables::ConstIterator ConstIterator; //!< Iterator over constant attachables. - //********************************************************************************************** - - //**Constructors******************************************************************************** - /*!\name Constructors */ - //@{ - explicit inline AttachableStorage( SizeType initCapacity = 100 ); - //@} - //********************************************************************************************** - - //**Utility functions*************************************************************************** - /*!\name Utility functions */ - //@{ - inline bool isEmpty() const; - inline SizeType size () const; - inline Iterator begin (); - inline ConstIterator begin () const; - inline Iterator end (); - inline ConstIterator end () const; - inline Iterator find ( id_t sid ); - inline ConstIterator find ( id_t sid ) const; - inline Iterator find ( ConstAttachableID attachable ); - inline ConstIterator find ( ConstAttachableID attachable ) const; - //@} - //********************************************************************************************** - - //**Add/Remove functions************************************************************************ - /*!\name Add/Remove functions */ - //@{ - inline void add ( AttachableID attachable ); - inline Iterator remove( Iterator pos ); - //@} - //********************************************************************************************** - -private: - //**Member variables**************************************************************************** - /*!\name Member variables */ - //@{ - Attachables attachables_; //!< The currently existing attachables. - //@} - //********************************************************************************************** - - //**Private struct Compare********************************************************************** - /*! \cond internal */ - /*!\brief Helper class for the find() function. */ - struct Compare : public std::binary_function<AttachableID,id_t,bool> - { - //**Binary function call operator************************************************************ - /*!\name Binary function call operator */ - //@{ - inline bool operator()( ConstAttachableID attachable, id_t sid ) const { - return attachable->getSystemID() < sid; - } - inline bool operator()( id_t sid, ConstAttachableID attachable ) const { - return sid < attachable->getSystemID(); - } - inline bool operator()( ConstAttachableID attachable1, ConstAttachableID attachable2 ) const { - return attachable1->getSystemID() < attachable2->getSystemID(); - } - //@} - //******************************************************************************************* - }; - /*! \endcond */ - //********************************************************************************************** - - //**Friend declarations************************************************************************* - /*! \cond internal */ - friend class Attachable; - /*! \endcond */ - //********************************************************************************************** -}; -//************************************************************************************************* - - - - -//================================================================================================= -// -// CONSTRUCTORS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Standard constructor for the AttachableStorage. - * - * \param initCapacity The initial capacity of the attachable storage. - */ -inline AttachableStorage::AttachableStorage( SizeType initCapacity ) - : attachables_( initCapacity ) -{} -//************************************************************************************************* - - - - -//================================================================================================= -// -// UTILITY FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Returns \a true if the attachable storage contains no attachables. - * - * \return \a true if the attachable storage is empty, \a false if it is not. - */ -inline bool AttachableStorage::isEmpty() const -{ - return attachables_.isEmpty(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns the number of attachables contained in the attachable storage. - * - * \return The number of attachables. - */ -inline AttachableStorage::SizeType AttachableStorage::size() const -{ - return attachables_.size(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator to the first contained attachable. - * - * \return Iterator to the first contained attachable. - */ -inline AttachableStorage::Iterator AttachableStorage::begin() -{ - return attachables_.begin(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns a constant iterator to the first contained attachable. - * - * \return Constant iterator to the first contained attachable. - */ -inline AttachableStorage::ConstIterator AttachableStorage::begin() const -{ - return attachables_.begin(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator just past the last contained attachable. - * - * \return Iterator just past the last contained attachable. - */ -inline AttachableStorage::Iterator AttachableStorage::end() -{ - return attachables_.end(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns a constant iterator just past the last contained attachable. - * - * \return Constant iterator just past the last contained attachable. - */ -inline AttachableStorage::ConstIterator AttachableStorage::end() const -{ - return attachables_.end(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Finding an attachable with a certain unique system-specific ID. - * - * \param sid The unique system-specific ID for the search. - * \return Iterator to the attachable with system-specific ID \a sid or an iterator just past the end. - * - * This function finds the attachable with the system-specific ID \a sid. In case the attachable - * is found, the function returns an iterator to the attachable. Otherwise, the function returns - * an iterator just past the end of last attachable contained in the attachable storage. - */ -inline AttachableStorage::Iterator AttachableStorage::find( id_t sid ) -{ - Iterator pos = std::lower_bound( begin(), end(), sid, Compare() ); - if( pos != end() && pos->getSystemID() == sid ) - return pos; - else - return end(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Finding an attachable with a certain unique system-specific ID. - * - * \param sid The unique system-specific ID for the search. - * \return Constant iterator to the attachable with system-specific ID \a sid or a constant iterator just past the end. - * - * This function finds the attachable with the system-specific ID \a sid. In case the attachable - * is found, the function returns a constant iterator to the attachable. Otherwise, the function - * returns a constant iterator just past the end of last attachable contained in the attachable - * storage. - */ -inline AttachableStorage::ConstIterator AttachableStorage::find( id_t sid ) const -{ - ConstIterator pos = std::lower_bound( begin(), end(), sid, Compare() ); - if( pos != end() && pos->getSystemID() == sid ) - return pos; - else - return end(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Finding a specific attachable in the attachable storage. - * - * \param attachable The given attachable for the search. - * \return Iterator to the given attachable or an iterator just past the end. - * - * This function finds the attachable in the attachable storage. In case the attachable is found, - * the function returns an iterator to the attachable. Otherwise, the function returns an iterator - * just past the end of last attachable contained in the attachable storage. - */ -inline AttachableStorage::Iterator AttachableStorage::find( ConstAttachableID attachable ) -{ - return find( attachable->getSystemID() ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Finding a specific attachable in the attachable storage. - * - * \param attachable The given attachable for the search. - * \return Iterator to the given attachable or an iterator just past the end. - * - * This function finds the attachable in the attachable storage. In case the attachable is found, - * the function returns an iterator to the attachable. Otherwise, the function returns an iterator - * just past the end of last attachable contained in the attachable storage. - */ -inline AttachableStorage::ConstIterator AttachableStorage::find( ConstAttachableID attachable ) const -{ - return find( attachable->getSystemID() ); -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// ADD/REMOVE FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Adding an attachable to the attachable storage. - * - * \param attachable The new attachable to be added to the attachable storage. - * \return void - * - * This function adds an attachable to the attachable storage. - */ -inline void AttachableStorage::add( AttachableID attachable ) -{ - Iterator pos = std::lower_bound( begin(), end(), attachable->getSystemID(), Compare() ); - attachables_.insert( pos, attachable ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Removing an attachable from the attachable storage. - * - * \param pos The position of the attachable to be removed. - * \return Iterator to the attachable after the erased attachable. - * - * This function removes an attachable from the attachable storage. - */ -inline AttachableStorage::Iterator AttachableStorage::remove( Iterator pos ) -{ - WALBERLA_ASSERT( pos != end(), "Attachable is not contained in the attachable storage" ); - - return attachables_.erase( pos ); -} -//************************************************************************************************* - -} // namespace pe -} // namespace walberla diff --git a/src/pe/ccd/HashGrids.cpp b/src/pe/ccd/HashGrids.cpp index 8b7b001c7887d601ae6bab15cd00595bfc4a3cce..3eee9158b6fb6ce554e507fa3d2ce316295049eb 100644 --- a/src/pe/ccd/HashGrids.cpp +++ b/src/pe/ccd/HashGrids.cpp @@ -764,15 +764,15 @@ void HashGrids::reloadBodies() { clear(); - for (auto bodyIt = bodystorage_.begin(); bodyIt != bodystorage_.end(); ++bodyIt) + for (auto& body : bodystorage_) { - add( *bodyIt ); + add( &body ); } if( &bodystorage_ != &bodystorageShadowCopies_ ) { - for (auto bodyIt = bodystorageShadowCopies_.begin(); bodyIt != bodystorageShadowCopies_.end(); ++bodyIt) + for (auto& body : bodystorageShadowCopies_) { - add( *bodyIt ); + add( &body ); } } } @@ -872,46 +872,42 @@ void HashGrids::update(WcTimingTree* tt) // suitably sized cells (=> "addGrid()"). { - const auto end( bodystorage_.end() ); - for( auto bIt = bodystorage_.begin(); bIt != end; ++bIt ) + for( auto& body : bodystorage_ ) { - BodyID body = *bIt; - HashGrid* grid = static_cast<HashGrid*>( body->getGrid() ); + HashGrid* grid = static_cast<HashGrid*>( body.getGrid() ); if( grid != NULL ) { - real_t size = body->getAABBSize(); + real_t size = body.getAABBSize(); real_t cellSpan = grid->getCellSpan(); if( size >= cellSpan || size < ( cellSpan / hierarchyFactor ) ) { - grid->remove( body ); - addGrid( body ); + grid->remove( &body ); + addGrid( &body ); } else { - grid->update( body ); + grid->update( &body ); } } } } if( &bodystorage_ != &bodystorageShadowCopies_ ) { - const auto end( bodystorageShadowCopies_.end() ); - for( auto bIt = bodystorageShadowCopies_.begin(); bIt != end; ++bIt ) + for( auto& body : bodystorageShadowCopies_ ) { - BodyID body = *bIt; - HashGrid* grid = static_cast<HashGrid*>( body->getGrid() ); + HashGrid* grid = static_cast<HashGrid*>( body.getGrid() ); if( grid != NULL ) { - real_t size = body->getAABBSize(); + real_t size = body.getAABBSize(); real_t cellSpan = grid->getCellSpan(); if( size >= cellSpan || size < ( cellSpan / hierarchyFactor ) ) { - grid->remove( body ); - addGrid( body ); + grid->remove( &body ); + addGrid( &body ); } else { - grid->update( body ); + grid->update( &body ); } } } @@ -966,7 +962,7 @@ PossibleContacts& HashGrids::generatePossibleContacts( WcTimingTree* tt ) } // Test all bodies stored in 'grid' against all bodies stored in 'globalStorage_'. for( auto bIt = globalStorage_.begin(); bIt < globalStorage_.end(); ++bIt ) { - collide( *a, *bIt, contacts_ ); + collide( *a, &(*bIt), contacts_ ); } } } @@ -982,7 +978,7 @@ PossibleContacts& HashGrids::generatePossibleContacts( WcTimingTree* tt ) // Pairwise test (=> contact generation) for all bodies that are stored in 'nonGridBodies_' with global bodies. for( auto bIt = globalStorage_.begin(); bIt < globalStorage_.end(); ++bIt ) { - collide( *aIt, *bIt, contacts_ ); + collide( *aIt, &(*bIt), contacts_ ); } } if (tt != NULL) tt->stop("Detection"); diff --git a/src/pe/ccd/SimpleCCD.cpp b/src/pe/ccd/SimpleCCD.cpp index dee87d16b92bd0b26120cee2c63d61d7eac93636..2fcb2b9e6506767a21ae77c7d0903e10ac0c0b0e 100644 --- a/src/pe/ccd/SimpleCCD.cpp +++ b/src/pe/ccd/SimpleCCD.cpp @@ -70,12 +70,12 @@ PossibleContacts& SimpleCCD::generatePossibleContacts( WcTimingTree* tt ){ for (auto it2 = globalStorage_.begin(); it2 != globalStorage_.end(); ++it2) { - if (!((*it1)->hasInfiniteMass() && (*it2)->hasInfiniteMass())) + if (!((*it1)->hasInfiniteMass() && it2->hasInfiniteMass())) { - if ( (*it1)->getSystemID() > (*it2)->getSystemID() ) - contacts_.push_back(std::make_pair(*it2, *it1)); + if ( (*it1)->getSystemID() > it2->getSystemID() ) + contacts_.push_back(std::make_pair(it2.getBodyID(), *it1)); else - contacts_.push_back(std::make_pair(*it1, *it2)); + contacts_.push_back(std::make_pair(*it1, it2.getBodyID())); } } } diff --git a/src/pe/collision/EPA.cpp b/src/pe/collision/EPA.cpp index 2e0d0e889c2911827f298a7a76ca578513c22997..415ef46d5f9b51f42f9d5c5b5e9480bf1401c72a 100644 --- a/src/pe/collision/EPA.cpp +++ b/src/pe/collision/EPA.cpp @@ -119,7 +119,7 @@ inline bool EPA::EPA_Triangle::link( size_t edge0, EPA_Triangle* tria, size_t ed tria->adjEdges_[edge1] = edge0; bool b = indices_[edge0] == tria->indices_[(edge1+1)%3] && - indices_[(edge0+1)%3] == tria->indices_[edge1]; + indices_[(edge0+1)%3] == tria->indices_[edge1]; return b; } //************************************************************************************************* @@ -145,7 +145,7 @@ inline void EPA::EPA_Triangle::silhouette( const Vec3& w, EPA_EdgeBuffer& edgeBu /*! \brief Recursive silhuette finding method. */ void EPA::EPA_Triangle::silhouette( size_t index, const Vec3& w, - EPA_EdgeBuffer& edgeBuffer ) + EPA_EdgeBuffer& edgeBuffer ) { if (!obsolete_) { real_t test = (closest_ * w); @@ -184,7 +184,7 @@ const long double EpsilonRelEPA< long double >::value = static_cast< long double /*! \brief Does an EPA computation with contactthreshold added. Use Default relative Error. */ bool EPA::doEPAcontactThreshold( GeomPrimitive &geom1, GeomPrimitive &geom2, const GJK& gjk, Vec3& retNormal, - Vec3& contactPoint, real_t& penetrationDepth){ + Vec3& contactPoint, real_t& penetrationDepth){ //Default relative epsilon return doEPA(geom1, geom2, gjk, retNormal, contactPoint, penetrationDepth, contactThreshold, EpsilonRelEPA<real_t>::value); @@ -196,7 +196,7 @@ bool EPA::doEPAcontactThreshold( GeomPrimitive &geom1, GeomPrimitive &geom2, con /*! \brief Does an EPA computation with contactThreshold added. Relative Error can be specified. */ bool EPA::doEPAcontactThreshold( GeomPrimitive &geom1, GeomPrimitive &geom2, const GJK& gjk, Vec3& retNormal, - Vec3& contactPoint, real_t& penetrationDepth, real_t eps_rel){ + Vec3& contactPoint, real_t& penetrationDepth, real_t eps_rel){ return doEPA(geom1, geom2, gjk, retNormal, contactPoint, penetrationDepth, contactThreshold, eps_rel); } @@ -207,7 +207,7 @@ bool EPA::doEPAcontactThreshold( GeomPrimitive &geom1, GeomPrimitive &geom2, con /*! \brief Does an EPA computation with margin added. Use Default relative Error. */ bool EPA::doEPAmargin( GeomPrimitive &geom1, GeomPrimitive &geom2, const GJK& gjk, Vec3& retNormal, - Vec3& contactPoint, real_t& penetrationDepth, real_t margin){ + Vec3& contactPoint, real_t& penetrationDepth, real_t margin){ //Default relative epsilon return doEPA(geom1, geom2, gjk, retNormal, contactPoint, penetrationDepth, margin, EpsilonRelEPA<real_t>::value); } @@ -218,7 +218,7 @@ bool EPA::doEPAmargin( GeomPrimitive &geom1, GeomPrimitive &geom2, const GJK& gj /*! \brief Does an epa computation with contact margin added and specified realtive error. */ bool EPA::doEPA( GeomPrimitive &geom1, GeomPrimitive &geom2, const GJK& gjk, Vec3& retNormal, - Vec3& contactPoint, real_t& penetrationDepth, real_t margin, real_t eps_rel ) + Vec3& contactPoint, real_t& penetrationDepth, real_t margin, real_t eps_rel ) { //have in mind that we use a support mapping which blows up the objects a wee bit so //zero penetraion aka toching contact means that the original bodies have a distance of 2*margin between them @@ -271,8 +271,10 @@ bool EPA::doEPA( GeomPrimitive &geom1, GeomPrimitive &geom2, const GJK& gjk, Vec std::make_heap(entryHeap.begin(), entryHeap.end(), EPA::EPA_TriangleComp()); EPA_Triangle* current = NULL; + numIterations_ = 0; //EPA Main-Loop do { + ++numIterations_; std::pop_heap(entryHeap.begin(), entryHeap.end(), EPA::EPA_TriangleComp()); current = entryHeap.back(); entryHeap.pop_back(); @@ -310,38 +312,49 @@ bool EPA::doEPA( GeomPrimitive &geom1, GeomPrimitive &geom2, const GJK& gjk, Vec //std::cerr << "New upper bound: " << farDist*farDist << std::endl; upperBoundSqr = std::min(upperBoundSqr, farDist*farDist); + + //Try to approximate the new surface with a sphere - Vec3 ctr; - real_t radius2 = calculateCircle(support, epaVolume[(*current)[0]], - epaVolume[(*current)[1]], epaVolume[(*current)[2]], ctr); - if(radius2 > real_t(0.0)){ //if a Sphere exists - //std::cerr << "Circle created with center at " << ctr << ". r2=" << radius2 << std::endl; - real_t center_len = ctr.length(); - real_t circle_dist = (std::sqrt(radius2) - center_len); //Distance from center to the spheres surface - //Check if the circle matches the bounds given by EPA and limit max error to ca. 5% - if(circle_dist*circle_dist <= upperBoundSqr && circle_dist*circle_dist >= lowerBoundSqr && - (circle_dist*circle_dist)/lowerBoundSqr < real_t(1.10) && !floatIsEqual(center_len, real_t(0.0))) { - - ctr = -1*ctr.getNormalized(); - //std::cerr << "New support direction: " << ctr << std::endl; - pushSupportMargin(geom1, geom2, ctr, margin, epaVolume, supportA, supportB); - support = epaVolume.back(); - // Check if support is in expected direction - - if(floatIsEqual((support % ctr).sqrLength()/support.sqrLength(), real_t(0.0))){ //Accept sphere - - contactPoint = real_t(0.5) * (supportA.back() + supportB.back()); - penetrationDepth = -support.length()+ real_t(2.0) * margin; - retNormal = -ctr; - //std::cerr << "Found penetration depth " << penetrationDepth << " with CurvedEPA!" << std::endl; - if(penetrationDepth < contactThreshold){ - return true; - }else{ - return false; - } - } else { //Reject sphere - removeSupportMargin(epaVolume, supportA, supportB); + if (bUseSphereOptimization_) + { + Vec3 ctr; + real_t radius2 = calculateCircle(support, + epaVolume[(*current)[0]], + epaVolume[(*current)[1]], + epaVolume[(*current)[2]], + ctr); + if(radius2 > real_t(0.0)){ //if a Sphere exists + //std::cerr << "Circle created with center at " << ctr << ". r2=" << radius2 << std::endl; + real_t center_len = ctr.length(); + real_t circle_dist = (std::sqrt(radius2) - center_len); //Distance from center to the spheres surface + //Check if the circle matches the bounds given by EPA and limit max error to ca. 5% + if (circle_dist*circle_dist <= upperBoundSqr && + circle_dist*circle_dist >= lowerBoundSqr && + (circle_dist*circle_dist) < real_t(1.10) * lowerBoundSqr && + !floatIsEqual(center_len, real_t(0.0))) + { + const auto ilen = real_t(1.0) / center_len; + ctr *= -ilen; + //std::cerr << "New support direction: " << ctr << std::endl; + pushSupportMargin(geom1, geom2, ctr, margin, epaVolume, supportA, supportB); support = epaVolume.back(); + // Check if support is in expected direction + + if(floatIsEqual((support % ctr).sqrLength()/support.sqrLength(), real_t(0.0))) + { //Accept sphere + contactPoint = real_t(0.5) * (supportA.back() + supportB.back()); + penetrationDepth = -support.length() + real_t(2.0) * margin; + retNormal = -ctr; + //std::cerr << "Found penetration depth " << penetrationDepth << " with CurvedEPA!" << std::endl; + if(penetrationDepth < contactThreshold){ + return true; + }else{ + return false; + } + } else { //Reject sphere + removeSupportMargin(epaVolume, supportA, supportB); + support = epaVolume.back(); + } } } } @@ -853,26 +866,20 @@ inline bool EPA::searchTetrahedron(GeomPrimitive &geom1, GeomPrimitive &geom2, s */ inline real_t EPA::calculateCircle(const Vec3& A, const Vec3& B, const Vec3& C, const Vec3& D, Vec3& center ){ - real_t l1, l2, l3, d1, d2, d3; - l1 = (A-B).length(); /* These three sqrt evaluations are necessary */ - l2 = (A-C).length(); - l3 = (A-D).length(); - - Vec3 n1, n2, n3; - n1 = (real_t(1.0)/l1)*(A-B); - n2 = (real_t(1.0)/l2)*(A-C); - n3 = (real_t(1.0)/l3)*(A-D); + const Vec3 n1(A-B); + const Vec3 n2(A-C); + const Vec3 n3(A-D); // Here we already see if such circle exists. - real_t det = n1 * (n2 % n3); + const real_t det = n1 * (n2 % n3); if(std::fabs(det) < math::Limits<real_t>::fpuAccuracy()){ //no circle exists. Leave center untouched, and return -1.0 return real_t(-1.0); } - real_t Alen = A.sqrLength(); - d1 = (Alen - B.sqrLength())/(real_t(2.0)*l1); - d2 = (Alen - C.sqrLength())/(real_t(2.0)*l2); - d3 = (Alen - D.sqrLength())/(real_t(2.0)*l3); + const real_t Alen = A.sqrLength(); + const real_t d1 = (Alen - B.sqrLength())*real_t(0.5); + const real_t d2 = (Alen - C.sqrLength())*real_t(0.5); + const real_t d3 = (Alen - D.sqrLength())*real_t(0.5); //Apply solution formula center = (real_t(1.0)/det)*(d1 * (n2 % n3) + d2 * (n3 % n1) + d3 * (n1 % n2)); diff --git a/src/pe/collision/EPA.h b/src/pe/collision/EPA.h index da611ecaec9e01165899874d5769ea32511befd1..a318e7e578323e4237e51492b3ef250d7838427c 100644 --- a/src/pe/collision/EPA.h +++ b/src/pe/collision/EPA.h @@ -86,6 +86,8 @@ public: bool doEPA( GeomPrimitive &geom1, GeomPrimitive &geom2, const GJK& gjk, Vec3& normal, Vec3& contactPoint, real_t& penetrationDepth, real_t margin, real_t eps_rel ); + + //@} //********************************************************************************************** @@ -100,6 +102,11 @@ public: inline size_t getMaxTriangles() {return maxTriangles_;} + inline int getNumIterations() const {return numIterations_; } + + inline bool useSphereOptimization() const {return bUseSphereOptimization_; } + inline void useSphereOptimization(const bool useIt) {bUseSphereOptimization_ = useIt;} + //@} //********************************************************************************************** @@ -143,6 +150,9 @@ private: //EPA constants size_t maxSupportPoints_ = 100; size_t maxTriangles_ = 200; + + int numIterations_ = 0; + bool bUseSphereOptimization_ = false; }; //************************************************************************************************* diff --git a/src/pe/collision/GJKEPAHelper.cpp b/src/pe/collision/GJKEPAHelper.cpp deleted file mode 100644 index d8316cd6db099983dc7b0772f6d506e9ac23cd3a..0000000000000000000000000000000000000000 --- a/src/pe/collision/GJKEPAHelper.cpp +++ /dev/null @@ -1,79 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file GJKHelper.cpp -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -// -//====================================================================================================================== - -//************************************************************************************************* -// Includes -//************************************************************************************************* - -#include "GJKEPAHelper.h" - -#include "pe/rigidbody/GeomPrimitive.h" - -extern "C" { - #include "pe/extern/libccd/ccd/ccd.h" - #include "pe/extern/libccd/ccd/quat.h" -} - -#include "core/logging/Logging.h" - -namespace walberla { -namespace pe { - -Vec3 convertVec3(const ccd_vec3_t& vec) { return Vec3(real_c(vec.v[0]), real_c(vec.v[1]), real_c(vec.v[2])); } -ccd_vec3_t convertVec3(const Vec3& vec) { ccd_vec3_t ret; ret.v[0] = vec[0]; ret.v[1] = vec[1]; ret.v[2] = vec[2]; return ret; } - -void support(const void *obj, const ccd_vec3_t *dir, ccd_vec3_t *vec) -{ - ConstGeomID bd = reinterpret_cast<ConstGeomID> (obj); - Vec3 d = convertVec3(*dir); - Vec3 sup = bd->support( d ); - *vec = convertVec3(sup); -} - -bool collideGJK( ConstGeomID bd1, - ConstGeomID bd2, - Vec3& contactPoint, - Vec3& contactNormal, - real_t& penetrationDepth, - const unsigned long numIterations, - const real_t epaTol ) -{ - ccd_t ccd; - CCD_INIT(&ccd); // initialize ccd_t struct - - // set up ccd_t struct - ccd.support1 = support; // support function for first object - ccd.support2 = support; // support function for second object - ccd.max_iterations = numIterations; // maximal number of iterations - ccd.epa_tolerance = epaTol; - - ccd_vec3_t dir, pos; - ccd_real_t penetrationDepthCCD; - int intersect = ccdGJKPenetration(reinterpret_cast<const void*> (bd1), reinterpret_cast<const void*> (bd2), &ccd, &penetrationDepthCCD, &dir, &pos); - penetrationDepth = real_c(penetrationDepthCCD); - contactPoint = convertVec3(pos); - contactNormal = -convertVec3(dir); - penetrationDepth *= -1; - - return (intersect == 0); -} - -} // namespace pe -} // namespace walberla diff --git a/src/pe/collision/GJKEPAHelper.h b/src/pe/collision/GJKEPAHelper.h deleted file mode 100644 index b1d73b1a19584a53449034529163c9247a5f230c..0000000000000000000000000000000000000000 --- a/src/pe/collision/GJKEPAHelper.h +++ /dev/null @@ -1,87 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file GJKHelper.h -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -// -//====================================================================================================================== - -#pragma once - -//************************************************************************************************* -// Includes -//************************************************************************************************* - -#include "pe/contact/Contact.h" -#include "pe/Types.h" - -#include "core/math/Vector3.h" - -namespace walberla { -namespace pe { - -static unsigned long maxGJKIterations = 100ul; -static real_t epaTolerance = real_t(0.000001); - -inline -void setMaxGJKIterations(const unsigned long& iter) -{ - maxGJKIterations = iter; -} -inline -unsigned long getMaxGJKIterations() -{ - return maxGJKIterations; -} - -inline -void setEPATolerance(const real_t& tol) -{ - epaTolerance = tol; -} -inline -real_t getEPATolerance() -{ - return epaTolerance; -} - -bool collideGJK( ConstGeomID bd1, - ConstGeomID bd2, - Vec3& contactPoint, - Vec3& contactNormal, - real_t& penetrationDepth, - const unsigned long numIterations = maxGJKIterations, - const real_t epaTol = epaTolerance ); - -template <typename Container> -bool collideGJK( GeomID bd1, - GeomID bd2, - Container& container, - const unsigned long numIterations = maxGJKIterations, - const real_t epaTol = epaTolerance ) -{ - real_t penetrationDepth; - Vec3 contactPoint; - Vec3 contactNormal; - bool retVal = collideGJK(bd1, bd2, contactPoint, contactNormal, penetrationDepth, numIterations, epaTol); - if (retVal) - { - container.push_back( Contact(bd1, bd2, contactPoint, contactNormal, penetrationDepth) ); - } - return retVal; -} - -} // namespace pe -} // namespace walberla diff --git a/src/pe/communication/DynamicMarshalling.h b/src/pe/communication/DynamicMarshalling.h index e2d2c4a6ceb2b4e35d1aad180c9b4700514bc03f..032708bff7ac44d5ece117697ea337097f6a1a66 100644 --- a/src/pe/communication/DynamicMarshalling.h +++ b/src/pe/communication/DynamicMarshalling.h @@ -91,7 +91,7 @@ private: , block_(block) {} template< typename BodyType > - BodyID operator()( BodyType* bd) { return instantiate( buffer_, domain_, block_, bd ); } + BodyPtr operator()( BodyType* bd) { return instantiate( buffer_, domain_, block_, bd ); } }; public: @@ -105,10 +105,10 @@ public: * The rigid body is casted dynamically to its original type and then marshalled. For recognition * an identifying tag is prepended. */ - static BodyID execute(mpi::RecvBuffer& buffer, const id_t typeID, const math::AABB& domain, const math::AABB& block) + static BodyPtr execute(mpi::RecvBuffer& buffer, const id_t typeID, const math::AABB& domain, const math::AABB& block) { UnmarshalFunctor func(buffer, domain, block); - return SingleCast<BodyTypeTuple, UnmarshalFunctor, BodyID>::execute (typeID, func); + return SingleCast<BodyTypeTuple, UnmarshalFunctor, BodyPtr>::execute (typeID, func); } }; diff --git a/src/pe/communication/Instantiate.h b/src/pe/communication/Instantiate.h index 6096c6552d3e21e63ec29a99efbefcfc0cfb20c3..f10a27dddab2efb0a4a6b9ae375110fce368dd29 100644 --- a/src/pe/communication/Instantiate.h +++ b/src/pe/communication/Instantiate.h @@ -55,7 +55,7 @@ void correctBodyPosition(const math::AABB& domain, const Vec3& center, Vec3& pos } template < class BodyT > -BodyT* instantiate( mpi::RecvBuffer& /*buffer*/, const math::AABB& /*domain*/, const math::AABB& /*block*/, BodyT*& /*newBody*/ ) +std::unique_ptr<BodyT> instantiate( mpi::RecvBuffer& /*buffer*/, const math::AABB& /*domain*/, const math::AABB& /*block*/, BodyT*& /*newBody*/ ) { WALBERLA_ABORT( "Body instantiation not implemented! (" << demangle(typeid(BodyT).name()) << ")" ); } diff --git a/src/pe/communication/ParseMessage.h b/src/pe/communication/ParseMessage.h index 5735beb152fb332ae5d007ad56115d339b6f5194..deea7db9689387c9adcd3f8dc4edccca02a8488a 100644 --- a/src/pe/communication/ParseMessage.h +++ b/src/pe/communication/ParseMessage.h @@ -64,17 +64,18 @@ void parseMessage(Owner sender, mpi::RecvBuffer& rb, const domain_decomposition: WALBERLA_LOG_DETAIL( "Received " << objparam.geomType_ << " copy notification from neighboring process with rank " << sender ); - BodyID obj = UnmarshalDynamically<BodyTypeTuple>::execute(rb, objparam.geomType_, blockStorage.getDomain(), block.getAABB()); + BodyPtr obj = UnmarshalDynamically<BodyTypeTuple>::execute(rb, objparam.geomType_, blockStorage.getDomain(), block.getAABB()); obj->setRemote( true ); + obj->MPITrait.setBlockState( sender.blockID_ ); + if (shadowStorage.find( obj->getSystemID() ) == shadowStorage.end()) { - WALBERLA_LOG_DETAIL( "Adding new shadow copy with id " << obj->getSystemID() << " to domain " << block.getAABB() << ".\n" << obj); - shadowStorage.add( obj ); + WALBERLA_LOG_DETAIL( "Adding new shadow copy with id " << obj->getSystemID() << " to domain " << block.getAABB() << ".\n" << *obj); + shadowStorage.add( std::move(obj) ); } else { WALBERLA_LOG_DETAIL( "Shadow copy with id " << obj->getSystemID() << " already existend."); } - obj->MPITrait.setBlockState( sender.blockID_ ); WALBERLA_LOG_DETAIL( "Processed " << objparam.geomType_ << " copy notification." ); @@ -88,7 +89,7 @@ void parseMessage(Owner sender, mpi::RecvBuffer& rb, const domain_decomposition: auto bodyIt = shadowStorage.find( objparam.sid_ ); WALBERLA_ASSERT_UNEQUAL( bodyIt, shadowStorage.end() ); - BodyID b( *bodyIt ); + BodyID b( bodyIt.getBodyID() ); WALBERLA_ASSERT( b->MPITrait.getOwner().blockID_ == sender.blockID_, "Update notifications must be sent by owner.\n" << b->MPITrait.getOwner().blockID_ << " != "<< sender.blockID_ ); WALBERLA_ASSERT( b->isRemote(), "Update notification must only concern shadow copies." ); @@ -112,10 +113,9 @@ void parseMessage(Owner sender, mpi::RecvBuffer& rb, const domain_decomposition: auto bodyIt = shadowStorage.find( objparam.sid_ ); if ( bodyIt == shadowStorage.end() ) WALBERLA_ABORT( "Object with id: " << objparam.sid_ << " not found in shadowStorage! Cannot transfer ownership! \nlocal domain: " << block.getAABB() ); - BodyID b( *bodyIt ); + BodyID b( bodyIt.getBodyID() ); - shadowStorage.release( b ); - localStorage.add( b ); + localStorage.add( shadowStorage.release( b ) ); WALBERLA_ASSERT( sender.blockID_ == b->MPITrait.getOwner().blockID_, "Migration notifications must be sent by previous owner.\n" << b->MPITrait.getOwner().blockID_ << " != "<< sender.blockID_ ); WALBERLA_ASSERT( b->isRemote(), "Bodies in migration notifications must be available as shadow copies in local process." ); @@ -143,7 +143,7 @@ void parseMessage(Owner sender, mpi::RecvBuffer& rb, const domain_decomposition: auto bodyIt = shadowStorage.find( objparam.sid_ ); WALBERLA_ASSERT_UNEQUAL( bodyIt, shadowStorage.end() ); - BodyID b( *bodyIt ); + BodyID b( bodyIt.getBodyID() ); WALBERLA_ASSERT( sender.blockID_ == b->MPITrait.getOwner().blockID_, "Remote migration notifications must be sent by previous owner.\n" << sender.blockID_ << " != " << b->MPITrait.getOwner().blockID_ ); WALBERLA_ASSERT( b->isRemote(), "Bodies in remote migration notifications must be available as shadow copies in local process." ); @@ -164,7 +164,7 @@ void parseMessage(Owner sender, mpi::RecvBuffer& rb, const domain_decomposition: // Remove shadow copy as prompted. auto bodyIt = shadowStorage.find( objparam.sid_ ); WALBERLA_ASSERT_UNEQUAL( bodyIt, shadowStorage.end() ); - BodyID b( *bodyIt ); + BodyID b( bodyIt.getBodyID() ); // TODO assert that we indeed do not need the shadow copy anymore WALBERLA_ASSERT( b->MPITrait.getOwner().blockID_ == sender.blockID_, "Only owner is allowed to send removal notifications.\n" << b->MPITrait.getOwner().blockID_ << " != "<< sender.blockID_ ); @@ -184,7 +184,7 @@ void parseMessage(Owner sender, mpi::RecvBuffer& rb, const domain_decomposition: // Remove invalid shadow copy. auto bodyIt = shadowStorage.find( objparam.sid_ ); WALBERLA_ASSERT_UNEQUAL( bodyIt, shadowStorage.end() ); - BodyID b( *bodyIt ); + BodyID b( bodyIt.getBodyID() ); WALBERLA_ASSERT( b->MPITrait.getOwner().blockID_ == sender.blockID_, "Only owner is allowed to send deletion notifications.\n" << b->MPITrait.getOwner().blockID_ << " != "<< sender.blockID_ ); @@ -203,7 +203,7 @@ void parseMessage(Owner sender, mpi::RecvBuffer& rb, const domain_decomposition: // Remove invalid shadow copy. auto bodyIt = localStorage.find( objparam.sid_ ); WALBERLA_ASSERT_UNEQUAL( bodyIt, localStorage.end() ); - BodyID b( *bodyIt ); + BodyID b( bodyIt.getBodyID() ); b->MPITrait.registerShadowOwner( objparam.newOwner_ ); @@ -221,7 +221,7 @@ void parseMessage(Owner sender, mpi::RecvBuffer& rb, const domain_decomposition: { auto bodyIt = localStorage.find( objparam.sid_ ); WALBERLA_ASSERT_UNEQUAL( bodyIt, localStorage.end() ); - BodyID b( *bodyIt ); + BodyID b( bodyIt.getBodyID() ); b->MPITrait.deregisterShadowOwner( sender ); b->MPITrait.unsetBlockState( sender.blockID_ ); } else @@ -229,7 +229,7 @@ void parseMessage(Owner sender, mpi::RecvBuffer& rb, const domain_decomposition: auto bodyIt = shadowStorage.find( objparam.sid_ ); if (bodyIt != shadowStorage.end() ) { - BodyID b( *bodyIt ); + BodyID b( bodyIt.getBodyID() ); b->MPITrait.unsetBlockState( sender.blockID_ ); } } @@ -260,7 +260,7 @@ void parseForceReduceMessage(Owner sender, mpi::RecvBuffer& rb, const domain_dec auto bodyIt = localStorage.find( objparam.sid_ ); WALBERLA_ASSERT_UNEQUAL( bodyIt, localStorage.end() ); - BodyID b( *bodyIt ); + BodyID b( bodyIt.getBodyID() ); WALBERLA_ASSERT( !b->isRemote(), "Update notification must only concern local bodies." ); @@ -292,7 +292,7 @@ void parseForceDistributeMessage(Owner sender, mpi::RecvBuffer& rb, const domain auto bodyIt = shadowStorage.find( objparam.sid_ ); WALBERLA_ASSERT_UNEQUAL( bodyIt, shadowStorage.end() ); - BodyID b( *bodyIt ); + BodyID b( bodyIt.getBodyID() ); WALBERLA_ASSERT( b->isRemote(), "Update notification must only concern shadow bodies." ); diff --git a/src/pe/communication/rigidbody/Box.h b/src/pe/communication/rigidbody/Box.h index 3a4c35a20e31b259cddd3fc0cfea4bf1d87d95d8..77f543cbc9183348f40a08d07fd95981b9800fdc 100644 --- a/src/pe/communication/rigidbody/Box.h +++ b/src/pe/communication/rigidbody/Box.h @@ -59,16 +59,17 @@ void marshal( mpi::SendBuffer& buffer, const Box& obj ); */ void unmarshal( mpi::RecvBuffer& buffer, BoxParameters& objparam ); //************************************************************************************************* -inline BoxID instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, BoxID& newBody ) +inline BoxPtr instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, BoxID& newBody ) { BoxParameters subobjparam; unmarshal( buffer, subobjparam ); correctBodyPosition(domain, block.center(), subobjparam.gpos_); - newBody = new Box( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.lengths_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ ); - newBody->setLinearVel( subobjparam.v_ ); - newBody->setAngularVel( subobjparam.w_ ); - newBody->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ ); - return newBody; + auto bx = std::make_unique<Box>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.lengths_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ ); + bx->setLinearVel( subobjparam.v_ ); + bx->setAngularVel( subobjparam.w_ ); + bx->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ ); + newBody = bx.get(); + return bx; } } // namespace communication diff --git a/src/pe/communication/rigidbody/Capsule.h b/src/pe/communication/rigidbody/Capsule.h index 7f99b1d1d47d7fb4e96713213f3ecababd718915..3ef02f07d1d4b95fbb3010be10e61eb158772cca 100644 --- a/src/pe/communication/rigidbody/Capsule.h +++ b/src/pe/communication/rigidbody/Capsule.h @@ -61,16 +61,17 @@ void unmarshal( mpi::RecvBuffer& buffer, CapsuleParameters& objparam ); //************************************************************************************************* -inline CapsuleID instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, CapsuleID& newBody ) +inline CapsulePtr instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, CapsuleID& newBody ) { CapsuleParameters subobjparam; unmarshal( buffer, subobjparam ); correctBodyPosition(domain, block.center(), subobjparam.gpos_); - newBody = new Capsule( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.radius_, subobjparam.length_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ ); - newBody->setLinearVel( subobjparam.v_ ); - newBody->setAngularVel( subobjparam.w_ ); - newBody->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ ); - return newBody; + auto cp = std::make_unique<Capsule>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.radius_, subobjparam.length_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ ); + cp->setLinearVel( subobjparam.v_ ); + cp->setAngularVel( subobjparam.w_ ); + cp->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ ); + newBody = cp.get(); + return cp; } } // namespace communication diff --git a/src/pe/communication/rigidbody/Ellipsoid.h b/src/pe/communication/rigidbody/Ellipsoid.h index 57916d268a30dbfea187071a18b4270ee63c83f3..a292c5b1dd1bc9bfbd2fb487260571fa26bc9756 100644 --- a/src/pe/communication/rigidbody/Ellipsoid.h +++ b/src/pe/communication/rigidbody/Ellipsoid.h @@ -61,16 +61,17 @@ void unmarshal( mpi::RecvBuffer& buffer, EllipsoidParameters& objparam ); //************************************************************************************************* -inline EllipsoidID instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, EllipsoidID& newBody ) +inline EllipsoidPtr instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, EllipsoidID& newBody ) { EllipsoidParameters subobjparam; unmarshal( buffer, subobjparam ); correctBodyPosition(domain, block.center(), subobjparam.gpos_); - newBody = new Ellipsoid( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.semiAxes_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ ); - newBody->setLinearVel( subobjparam.v_ ); - newBody->setAngularVel( subobjparam.w_ ); - newBody->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ ); - return newBody; + auto el = std::make_unique<Ellipsoid>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.semiAxes_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ ); + el->setLinearVel( subobjparam.v_ ); + el->setAngularVel( subobjparam.w_ ); + el->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ ); + newBody = el.get(); + return el; } } // namespace communication diff --git a/src/pe/communication/rigidbody/Sphere.h b/src/pe/communication/rigidbody/Sphere.h index 55881f65aa0e3c5e02cd0ea099093dd16ef45379..3e7da560142c29a93161b691975f403808f09fba 100644 --- a/src/pe/communication/rigidbody/Sphere.h +++ b/src/pe/communication/rigidbody/Sphere.h @@ -61,16 +61,17 @@ void unmarshal( mpi::RecvBuffer& buffer, SphereParameters& objparam ); //************************************************************************************************* -inline SphereID instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, SphereID& newBody ) +inline SpherePtr instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, SphereID& newBody ) { SphereParameters subobjparam; unmarshal( buffer, subobjparam ); correctBodyPosition(domain, block.center(), subobjparam.gpos_); - newBody = new Sphere( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.radius_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ ); - newBody->setLinearVel( subobjparam.v_ ); - newBody->setAngularVel( subobjparam.w_ ); - newBody->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ ); - return newBody; + auto sp = std::make_unique<Sphere>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.radius_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ ); + sp->setLinearVel( subobjparam.v_ ); + sp->setAngularVel( subobjparam.w_ ); + sp->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ ); + newBody = sp.get(); + return sp; } } // namespace communication diff --git a/src/pe/communication/rigidbody/Squirmer.h b/src/pe/communication/rigidbody/Squirmer.h index 9029c93586fa36c5d3b4e29d2aaefe74a4d5a4d1..3c9b3fbe094c6cef756168c6bfd63078825f001c 100644 --- a/src/pe/communication/rigidbody/Squirmer.h +++ b/src/pe/communication/rigidbody/Squirmer.h @@ -61,16 +61,17 @@ void unmarshal( mpi::RecvBuffer& buffer, SquirmerParameters& objparam ); //************************************************************************************************* -inline SquirmerID instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, SquirmerID& newBody ) +inline SquirmerPtr instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, SquirmerID& newBody ) { SquirmerParameters subobjparam; unmarshal( buffer, subobjparam ); correctBodyPosition(domain, block.center(), subobjparam.gpos_); - newBody = new Squirmer( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.radius_, subobjparam.squirmerVelocity_, subobjparam.squirmerBeta_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ ); - newBody->setLinearVel( subobjparam.v_ ); - newBody->setAngularVel( subobjparam.w_ ); - newBody->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ ); - return newBody; + auto sq = std::make_unique<Squirmer>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.radius_, subobjparam.squirmerVelocity_, subobjparam.squirmerBeta_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ ); + sq->setLinearVel( subobjparam.v_ ); + sq->setAngularVel( subobjparam.w_ ); + sq->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ ); + newBody = sq.get(); + return sq; } } // namespace communication diff --git a/src/pe/communication/rigidbody/Union.h b/src/pe/communication/rigidbody/Union.h index 69c2d6bb172ac8589b56f68e7ecc2946ac0b471f..544c131efff56184a82296a67c073784b0f585a4 100644 --- a/src/pe/communication/rigidbody/Union.h +++ b/src/pe/communication/rigidbody/Union.h @@ -72,12 +72,12 @@ void marshal( mpi::SendBuffer& buffer, const Union<BodyTypeTuple>& obj ) buffer << static_cast<size_t> (obj.size()); // Encoding the number of contained bodies // Encoding the contained primitives - const typename Union<BodyTypeTuple>::ConstIterator begin( obj.begin() ); - const typename Union<BodyTypeTuple>::ConstIterator end ( obj.end() ); - for( typename Union<BodyTypeTuple>::ConstIterator body=begin; body!=end; ++body ) + const typename Union<BodyTypeTuple>::const_iterator begin( obj.begin() ); + const typename Union<BodyTypeTuple>::const_iterator end ( obj.end() ); + for( typename Union<BodyTypeTuple>::const_iterator body=begin; body!=end; ++body ) { buffer << body->getTypeID(); - MarshalDynamically<BodyTypeTuple>::execute( buffer, **body ); + MarshalDynamically<BodyTypeTuple>::execute( buffer, *body ); } } @@ -110,34 +110,35 @@ void unmarshal( mpi::RecvBuffer& buffer, UnionParameters& objparam ) template <typename BodyTypeTuple> -inline Union<BodyTypeTuple>* instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, Union<BodyTypeTuple>*& newBody ) +inline std::unique_ptr<Union<BodyTypeTuple>> instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, Union<BodyTypeTuple>*& newBody ) { UnionParameters subobjparam; unmarshal( buffer, subobjparam ); correctBodyPosition(domain, block.center(), subobjparam.gpos_); - newBody = new Union<BodyTypeTuple>( subobjparam.sid_, - subobjparam.uid_, - subobjparam.gpos_, - subobjparam.rpos_, - subobjparam.q_, - false, - subobjparam.communicating_, - subobjparam.infiniteMass_ ); - newBody->setLinearVel( subobjparam.v_ ); - newBody->setAngularVel( subobjparam.w_ ); - newBody->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ ); + auto un = std::make_unique<Union<BodyTypeTuple>>( subobjparam.sid_, + subobjparam.uid_, + subobjparam.gpos_, + subobjparam.rpos_, + subobjparam.q_, + false, + subobjparam.communicating_, + subobjparam.infiniteMass_ ); + un->setLinearVel( subobjparam.v_ ); + un->setAngularVel( subobjparam.w_ ); + un->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ ); // Decoding the contained primitives for( size_t i = 0; i < subobjparam.size_; ++i ) { decltype ( static_cast<BodyID>(nullptr)->getTypeID() ) type; buffer >> type; - BodyID obj = UnmarshalDynamically<BodyTypeTuple>::execute(buffer, type, domain, block); + BodyPtr obj( UnmarshalDynamically<BodyTypeTuple>::execute(buffer, type, domain, block) ); obj->setRemote( true ); - newBody->add(obj); + un->add(std::move(obj)); } - return newBody; + newBody = un.get(); + return un; } } // namespace communication diff --git a/src/pe/contact/Contact.cpp b/src/pe/contact/Contact.cpp index ed9e68e28cc7bff136a697d4b1716f3421f92a23..7bc7dc04127ff734e3153201f3037fb3663cf72e 100644 --- a/src/pe/contact/Contact.cpp +++ b/src/pe/contact/Contact.cpp @@ -62,17 +62,8 @@ Contact::Contact( GeomID g1, GeomID g2, const Vec3& gpos, const Vec3& normal, re WALBERLA_ASSERT_FLOAT_EQUAL( normal.sqrLength(), real_c(1), "Invalid contact normal\n" << g1 << "\n" << g2 ); WALBERLA_ASSERT( !( b1_->hasInfiniteMass() && b2_->hasInfiniteMass() ), "Invalid contact between two rigid bodies with infinite masses" ); - // Registering the contact with both attached rigid bodies -// if( !b1_->hasInfiniteMass() ) b1_->registerContact( this ); -// if( !b2_->hasInfiniteMass() ) b2_->registerContact( this ); - - // Merging the contact graph -// if( !b1_->hasInfiniteMass() && !b2_->hasInfiniteMass() ) -// mergeNodes( b1_, b2_ ); - // Debugging output WALBERLA_LOG_DETAIL( " => contact-id = " << id_ ); - } //************************************************************************************************* diff --git a/src/pe/cr/DEM.h b/src/pe/cr/DEM.h index 9d0887e774253fcfbb7c76e4ded484a30abbd843..dcc19af292c646addf2f0eac477d3c87e5a4218f 100644 --- a/src/pe/cr/DEM.h +++ b/src/pe/cr/DEM.h @@ -79,7 +79,7 @@ private: size_t numberOfContactsTreated_; }; -class DEM : public DEMSolver<IntegrateImplictEuler, ResolveContactSpringDashpotHaffWerner> +class DEM : public DEMSolver<IntegrateImplicitEuler, ResolveContactSpringDashpotHaffWerner> { public: DEM( const shared_ptr<BodyStorage>& globalBodyStorage @@ -88,8 +88,8 @@ public: , domain_decomposition::BlockDataID ccdID , domain_decomposition::BlockDataID fcdID , WcTimingTree* tt = NULL) - : DEMSolver<IntegrateImplictEuler, ResolveContactSpringDashpotHaffWerner>( - IntegrateImplictEuler(), ResolveContactSpringDashpotHaffWerner(), + : DEMSolver<IntegrateImplicitEuler, ResolveContactSpringDashpotHaffWerner>( + IntegrateImplicitEuler(), ResolveContactSpringDashpotHaffWerner(), globalBodyStorage, blockStorage, storageID, ccdID, fcdID, tt ) { } diff --git a/src/pe/cr/DEM.impl.h b/src/pe/cr/DEM.impl.h index c64669ba210b48ca9f8101d7c09883c10405cc73..a3560e50fd94ba9daf71b71032deaa4ad3a9ec58 100644 --- a/src/pe/cr/DEM.impl.h +++ b/src/pe/cr/DEM.impl.h @@ -120,25 +120,21 @@ void DEMSolver<Integrator,ContactResolver>::timestep( real_t dt ) { WALBERLA_LOG_DETAIL( "Time integration of body with system id " << bodyIt->getSystemID());// << "\n" << *bodyIt ); - // Resetting the contact node and removing all attached contacts - // bodyIt->resetNode(); - bodyIt->clearContacts(); - // Checking the state of the body WALBERLA_ASSERT( bodyIt->checkInvariants(), "Invalid body state detected" ); WALBERLA_ASSERT( !bodyIt->hasSuperBody(), "Invalid superordinate body detected" ); - // Moving the capsule according to the acting forces (don't move a sleeping capsule) + // Moving the body according to the acting forces (don't move a sleeping body) if( bodyIt->isAwake() && !bodyIt->hasInfiniteMass() ) { - integrate_( *bodyIt, dt, *this ); + integrate_( bodyIt.getBodyID(), dt, *this ); } // Resetting the acting forces bodyIt->resetForceAndTorque(); // Checking the state of the rigid body - WALBERLA_ASSERT( bodyIt->checkInvariants(), "Invalid capsule state detected" ); + WALBERLA_ASSERT( bodyIt->checkInvariants(), "Invalid body state detected" ); // Resetting the acting forces bodyIt->resetForceAndTorque(); @@ -147,9 +143,8 @@ void DEMSolver<Integrator,ContactResolver>::timestep( real_t dt ) if (tt_ != NULL) tt_->stop("Integration"); // Reset forces of shadow copies - for( auto bodyIt = shadowStorage.begin(); bodyIt != shadowStorage.end(); ++bodyIt ) { - bodyIt->clearContacts(); - bodyIt->resetForceAndTorque(); + for( auto& body : shadowStorage ) { + body.resetForceAndTorque(); } } diff --git a/src/pe/cr/HCSITS.impl.h b/src/pe/cr/HCSITS.impl.h index 457cd4c299c88731b6e35058e59706a34774ea59..314b3d1c1dae7313d706053d66011ebf62b7e540 100644 --- a/src/pe/cr/HCSITS.impl.h +++ b/src/pe/cr/HCSITS.impl.h @@ -154,6 +154,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d numContacts_ = 0; numContactsTreated_ = 0; + maximumPenetration_ = 0; if (tt_ != NULL) tt_->start("Simulation Step"); @@ -210,7 +211,6 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d contactCache.resize( numContactsMasked ); { - maximumPenetration_ = 0; size_t j = 0; for( size_t i = 0; i < numContacts; ++i ) @@ -290,7 +290,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d body->index_ = j; WALBERLA_CHECK( body->hasInfiniteMass(), "Global bodies need to have infinite mass as they are not communicated!" ); - initializeVelocityCorrections( *body, bodyCache.dv_[j], bodyCache.dw_[j], dt ); // use applied external forces to calculate starting velocity + initializeVelocityCorrections( body.getBodyID(), bodyCache.dv_[j], bodyCache.dw_[j], dt ); // use applied external forces to calculate starting velocity bodyCache.v_[j] = body->getLinearVel(); bodyCache.w_[j] = body->getAngularVel(); @@ -300,7 +300,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d body->wake(); // BUGFIX: Force awaking of all bodies! body->index_ = j; - initializeVelocityCorrections( *body, bodyCache.dv_[j], bodyCache.dw_[j], dt ); // use applied external forces to calculate starting velocity + initializeVelocityCorrections( body.getBodyID(), bodyCache.dv_[j], bodyCache.dw_[j], dt ); // use applied external forces to calculate starting velocity if( body->isAwake() && !body->hasInfiniteMass() ) { bodyCache.v_[j] = body->getLinearVel() + getGlobalLinearAcceleration() * dt; @@ -317,7 +317,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d body->wake(); // BUGFIX: Force awaking of all bodies! body->index_ = j; - initializeVelocityCorrections( *body, bodyCache.dv_[j], bodyCache.dw_[j], dt ); + initializeVelocityCorrections( body.getBodyID(), bodyCache.dv_[j], bodyCache.dw_[j], dt ); // Velocities of shadow copies will be initialized by velocity synchronization. #ifndef NDEBUG @@ -349,7 +349,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d body->index_ = j; WALBERLA_CHECK( body->hasInfiniteMass(), "Global bodies need to have infinite mass as they are not communicated!" ); - initializeVelocityCorrections( *body, bodyCache.dv_[j], bodyCache.dw_[j], dt ); // use applied external forces to calculate starting velocity + initializeVelocityCorrections( body.getBodyID(), bodyCache.dv_[j], bodyCache.dw_[j], dt ); // use applied external forces to calculate starting velocity bodyCache.v_[j] = body->getLinearVel(); bodyCache.w_[j] = body->getAngularVel(); @@ -457,10 +457,10 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d WALBERLA_LOG_DETAIL( "Integrating position of global body " << *body << " with velocity " << body->getLinearVel() << "" ); if (body->hasInfiniteMass()) { - integratePositions( *body, bodyCache.v_[j], bodyCache.w_[j], dt ); + integratePositions( body.getBodyID(), bodyCache.v_[j], bodyCache.w_[j], dt ); } else { - integratePositions( *body, bodyCache.v_[j] + bodyCache.dv_[j], bodyCache.w_[j] + bodyCache.dw_[j], dt ); + integratePositions( body.getBodyID(), bodyCache.v_[j] + bodyCache.dv_[j], bodyCache.w_[j] + bodyCache.dw_[j], dt ); } WALBERLA_LOG_DETAIL( "Result:\n" << *body << ""); } @@ -476,11 +476,11 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d BodyStorage& localStorage = (*storage)[0]; BodyStorage& shadowStorage = (*storage)[1]; - for( auto body = ConcatIterator<BodyStorage::Iterator> + for( auto body = ConcatIterator<BodyStorage::iterator> (localStorage.begin(), localStorage.end(), shadowStorage.begin(), - shadowStorage.end()); body != ConcatIterator<BodyStorage::Iterator>(); ++body ) + shadowStorage.end()); body != ConcatIterator<BodyStorage::iterator>(); ++body ) { if (!body->isCommunicating()) { @@ -492,10 +492,10 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d WALBERLA_LOG_DETAIL( "Integrating position of body with infinite mass " << *body << " with velocity " << bodyCache.v_[j] << "" ); if( body->hasInfiniteMass() ) { - integratePositions( *body, bodyCache.v_[j], bodyCache.w_[j], dt ); + integratePositions( &(*body), bodyCache.v_[j], bodyCache.w_[j], dt ); } else { - integratePositions( *body, bodyCache.v_[j] + bodyCache.dv_[j], bodyCache.w_[j] + bodyCache.dw_[j], dt ); + integratePositions( &(*body), bodyCache.v_[j] + bodyCache.dv_[j], bodyCache.w_[j] + bodyCache.dw_[j], dt ); } WALBERLA_LOG_DETAIL( "Result:\n" << *body << "" ); } @@ -1433,7 +1433,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::parseVelocityCorrection( auto bodyIt = bodyStorage.find( objparam.sid_ ); WALBERLA_ASSERT(bodyIt != bodyStorage.end(), "Body not found!"); - BodyID b( *bodyIt ); + BodyID b( bodyIt.getBodyID() ); bodyCache.v_[b->index_] += relaxationParam_*objparam.dv_; bodyCache.w_[b->index_] += relaxationParam_*objparam.dw_; @@ -1462,7 +1462,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::parseVelocityCorrectionS auto bodyIt = bodyStorage.find( objparam.sid_ ); WALBERLA_ASSERT(bodyIt != bodyStorage.end(), "Body not found!"); - BodyID b( *bodyIt ); + BodyID b( bodyIt.getBodyID() ); WALBERLA_ASSERT( b->isRemote(), "Update notification must only concern shadow copies." ); bodyCache.v_[b->index_] = objparam.dv_; @@ -1531,12 +1531,12 @@ inline void HardContactSemiImplicitTimesteppingSolvers::synchronizeVelocities( ) WALBERLA_LOG_DETAIL( "Sending velocity correction " << bodyCache.dv_[i] << ", " << bodyCache.dw_[i] << " of body " << body->getSystemID() << " to owner process " << body->MPITrait.getOwner() << "."); - packNotificationWithoutSender(body->MPITrait.getOwner(), sb, RigidBodyVelocityCorrectionNotification( *(*body), bodyCache.dv_[i], bodyCache.dw_[i] )); + packNotificationWithoutSender(body->MPITrait.getOwner(), sb, RigidBodyVelocityCorrectionNotification( *body, bodyCache.dv_[i], bodyCache.dw_[i] )); } for( auto bodyIt = localStorage.begin(); bodyIt != localStorage.end(); ++bodyIt ) { - BodyID b(*bodyIt); + BodyID b(bodyIt.getBodyID()); for (auto shadows = b->MPITrait.beginShadowOwners(); shadows != b->MPITrait.endShadowOwners(); ++shadows ) { recvRanks.insert(shadows->rank_); @@ -1630,7 +1630,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::synchronizeVelocities( ) mpi::SendBuffer& sb = syncVelBS.sendBuffer( shadow->rank_ ); if (sb.isEmpty()) sb << walberla::uint8_c(0); - packNotificationWithoutSender(*shadow, sb, RigidBodyVelocityCorrectionNotification( *(*body), bodyCache.v_[i], bodyCache.w_[i] )); + packNotificationWithoutSender(*shadow, sb, RigidBodyVelocityCorrectionNotification( *body, bodyCache.v_[i], bodyCache.w_[i] )); WALBERLA_LOG_DETAIL( "Sending velocity update " << bodyCache.v_[i] << ", " << bodyCache.w_[i] << " of body " << body->getSystemID() << " to process " << *shadow << " having a shadow copy."); } @@ -1638,7 +1638,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::synchronizeVelocities( ) for( auto bodyIt = shadowStorage.begin(); bodyIt != shadowStorage.end(); ++bodyIt ) { - BodyID b(*bodyIt); + BodyID b(bodyIt.getBodyID()); recvRanks.insert(b->MPITrait.getOwner().rank_); } } @@ -1795,10 +1795,6 @@ inline void HardContactSemiImplicitTimesteppingSolvers::integratePositions( Body if ( body->isFixed() ) return; - // Resetting the contact node and removing all attached contacts - body->resetNode(); - body->clearContacts(); - if( body->isAwake() ) { if ( isSpeedLimiterActive() ) diff --git a/src/pe/cr/Integrators.h b/src/pe/cr/Integrators.h index 30b56e50a9e308917872d03156447d9e3b520157..1ea365f6661f542c73fde4ad31255cb5b18c2097 100644 --- a/src/pe/cr/Integrators.h +++ b/src/pe/cr/Integrators.h @@ -30,7 +30,7 @@ namespace pe { namespace cr { //************************************************************************************************* -/*!\brief Integrate the trajectory of one body using implict Euler. +/*!\brief Integrate the trajectory of one body using implicit Euler. * * \param id Body ID. * \param dt Time step size. @@ -40,7 +40,7 @@ namespace cr { * The implicit Euler algorithm, also known as backward Euler, is used. It is a first-order * integrator that does conserves energy (i.e. it is symplectic.) */ -class IntegrateImplictEuler { +class IntegrateImplicitEuler { public: void operator()( BodyID id, real_t dt, ICR & solver ) const { @@ -72,7 +72,7 @@ public: // Setting the axis-aligned bounding box id->calcBoundingBox(); - // Calculating the current motion of the capsule + // Calculating the current motion of the body id->calcMotion(); } }; @@ -88,7 +88,7 @@ public: * The explicit Euler algorithm, also known as forward Euler, is used. It is a first-order * integrator that does not conserve energy (i.e. it is not symplectic.) */ -class IntegrateExplictEuler { +class IntegrateExplicitEuler { public: void operator()( BodyID id, real_t dt, ICR & solver ) const { @@ -120,7 +120,7 @@ public: // Setting the axis-aligned bounding box id->calcBoundingBox(); - // Calculating the current motion of the capsule + // Calculating the current motion of the body id->calcMotion(); } }; diff --git a/src/pe/cr/PlainIntegrator.h b/src/pe/cr/PlainIntegrator.h index 271847f5d3d9b601452553d08d4a85bae8a4eb71..92abbbfb3746b59f08927fb9222b4b72bd00045f 100644 --- a/src/pe/cr/PlainIntegrator.h +++ b/src/pe/cr/PlainIntegrator.h @@ -61,14 +61,14 @@ private: WcTimingTree* tt_; }; -class PlainIntegrator : public PlainIntegratorSolver<IntegrateImplictEuler> +class PlainIntegrator : public PlainIntegratorSolver<IntegrateImplicitEuler> { public: PlainIntegrator( const shared_ptr<BodyStorage>& globalBodyStorage , const shared_ptr<BlockStorage>& blockStorage , domain_decomposition::BlockDataID storageID , WcTimingTree* tt = NULL) - : PlainIntegratorSolver<IntegrateImplictEuler>( IntegrateImplictEuler(), globalBodyStorage, blockStorage, + : PlainIntegratorSolver<IntegrateImplicitEuler>( IntegrateImplicitEuler(), globalBodyStorage, blockStorage, storageID, tt ) { } diff --git a/src/pe/cr/PlainIntegrator.impl.h b/src/pe/cr/PlainIntegrator.impl.h index 7b9c4ce45101e774ed936da68e81caab088f1f95..e2a45b2f8eda5405f858db551101d17f545e6537 100644 --- a/src/pe/cr/PlainIntegrator.impl.h +++ b/src/pe/cr/PlainIntegrator.impl.h @@ -65,23 +65,19 @@ void PlainIntegratorSolver<Integrator>::timestep( const real_t dt ) BodyStorage& localStorage = (*storage)[0]; for (auto bd = localStorage.begin(); bd != localStorage.end(); ++bd){ // Checking the state of the body - WALBERLA_ASSERT( bd->checkInvariants(), "Invalid capsule state detected" ); + WALBERLA_ASSERT( bd->checkInvariants(), "Invalid body state detected" ); WALBERLA_ASSERT( !bd->hasSuperBody(), "Invalid superordinate body detected" ); - // Resetting the contact node and removing all attached contacts - // bd->resetNode(); - bd->clearContacts(); - - // Moving the capsule according to the acting forces (don't move a sleeping capsule) + // Moving the body according to the acting forces (don't move a sleeping body) if( bd->isAwake() && !bd->hasInfiniteMass() ) { - integrate_( *bd, dt, *this ); + integrate_( bd.getBodyID(), dt, *this ); } // Resetting the acting forces bd->resetForceAndTorque(); - // Checking the state of the capsule - WALBERLA_ASSERT( bd->checkInvariants(), "Invalid capsule state detected" ); + // Checking the state of the body + WALBERLA_ASSERT( bd->checkInvariants(), "Invalid body state detected" ); } } if (tt_!=NULL) tt_->stop("Integrate Bodies"); diff --git a/src/pe/extern/libccd/.gitignore b/src/pe/extern/libccd/.gitignore deleted file mode 100644 index e3fa61345b7e1907936cb6042b7afbdb57c1ae68..0000000000000000000000000000000000000000 --- a/src/pe/extern/libccd/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -*.o -*.a -ccd/config.h -ccd/config.h.in - diff --git a/src/pe/extern/libccd/BSD-LICENSE b/src/pe/extern/libccd/BSD-LICENSE deleted file mode 100644 index 1cb2dc53db0a2e70017314ee88fd59eb375920c5..0000000000000000000000000000000000000000 --- a/src/pe/extern/libccd/BSD-LICENSE +++ /dev/null @@ -1,44 +0,0 @@ -libccd -------- - -Copyright (c)2010-2012 Daniel Fiser <danfis@danfis.cz>, -Intelligent and Mobile Robotics Group, Department of Cybernetics, -Faculty of Electrical Engineering, Czech Technical University in Prague. -All rights reserved. - - -This work was supported by SYMBRION and REPLICATOR projects. -The SYMBRION project is funded by European Commission within the work -"Future and Emergent Technologies Proactive" under grant agreement no. -216342. -The REPLICATOR project is funded within the work programme "Cognitive -Systems, Interaction, Robotics" under grant agreement no. 216240. -http://www.symbrion.eu/ -http://www.replicators.eu/ - - -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. - - - Neither the name of the University nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -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 HOLDER 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. diff --git a/src/pe/extern/libccd/alloc.h b/src/pe/extern/libccd/alloc.h deleted file mode 100644 index 7cba3a4d71e81c399282cb2a0298a39acf407d51..0000000000000000000000000000000000000000 --- a/src/pe/extern/libccd/alloc.h +++ /dev/null @@ -1,50 +0,0 @@ -/*** - * libccd - * --------------------------------- - * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> - * - * - * This file is part of libccd. - * - * Distributed under the OSI-approved BSD License (the "License"); - * see accompanying file BDS-LICENSE for details or see - * <http://www.opensource.org/licenses/bsd-license.php>. - * - * This software is distributed WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the License for more information. - */ - -#ifndef __CCD_ALLOC_H__ -#define __CCD_ALLOC_H__ - -#include <stdlib.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** - * Functions and macros required for memory allocation. - */ - -/* Memory allocation: */ -#define __CCD_ALLOC_MEMORY(type, ptr_old, size) \ - (type *)realloc((void *)ptr_old, (size)) - -/** Allocate memory for one element of type. */ -#define CCD_ALLOC(type) \ - __CCD_ALLOC_MEMORY(type, NULL, sizeof(type)) - -/** Allocate memory for array of elements of type type. */ -#define CCD_ALLOC_ARR(type, num_elements) \ - __CCD_ALLOC_MEMORY(type, NULL, sizeof(type) * (num_elements)) - -#define CCD_REALLOC_ARR(ptr, type, num_elements) \ - __CCD_ALLOC_MEMORY(type, ptr, sizeof(type) * (num_elements)) - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif /* __CCD_ALLOC_H__ */ diff --git a/src/pe/extern/libccd/ccd.c b/src/pe/extern/libccd/ccd.c deleted file mode 100644 index 79b2f42c91287df03239384228afe79aee6d6935..0000000000000000000000000000000000000000 --- a/src/pe/extern/libccd/ccd.c +++ /dev/null @@ -1,1001 +0,0 @@ -/*** - * libccd - * --------------------------------- - * Copyright (c)2012 Daniel Fiser <danfis@danfis.cz> - * - * - * This file is part of libccd. - * - * Distributed under the OSI-approved BSD License (the "License"); - * see accompanying file BDS-LICENSE for details or see - * <http://www.opensource.org/licenses/bsd-license.php>. - * - * This software is distributed WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the License for more information. - */ - -#include <stdio.h> -#include <float.h> -#include <ccd/ccd.h> -#include <ccd/vec3.h> -#include "simplex.h" -#include "polytope.h" -#include "alloc.h" -#include "dbg.h" - - -/** Performs GJK algorithm. Returns 0 if intersection was found and simplex - * is filled with resulting polytope. */ -static int __ccdGJK(const void *obj1, const void *obj2, - const ccd_t *ccd, ccd_simplex_t *simplex); - -/** Performs GJK+EPA algorithm. Returns 0 if intersection was found and - * pt is filled with resulting polytope and nearest with pointer to - * nearest element (vertex, edge, face) of polytope to origin. */ -static int __ccdGJKEPA(const void *obj1, const void *obj2, - const ccd_t *ccd, - ccd_pt_t *pt, ccd_pt_el_t **nearest); - - -/** Returns true if simplex contains origin. - * This function also alteres simplex and dir according to further - * processing of GJK algorithm. */ -static int doSimplex(ccd_simplex_t *simplex, ccd_vec3_t *dir); -static int doSimplex2(ccd_simplex_t *simplex, ccd_vec3_t *dir); -static int doSimplex3(ccd_simplex_t *simplex, ccd_vec3_t *dir); -static int doSimplex4(ccd_simplex_t *simplex, ccd_vec3_t *dir); - -/** d = a x b x c */ -_ccd_inline void tripleCross(const ccd_vec3_t *a, const ccd_vec3_t *b, - const ccd_vec3_t *c, ccd_vec3_t *d); - - -/** Transforms simplex to polytope. It is assumed that simplex has 4 - * vertices. */ -static int simplexToPolytope4(const void *obj1, const void *obj2, - const ccd_t *ccd, - ccd_simplex_t *simplex, - ccd_pt_t *pt, ccd_pt_el_t **nearest); - -/** Transforms simplex to polytope, three vertices required */ -static int simplexToPolytope3(const void *obj1, const void *obj2, - const ccd_t *ccd, - const ccd_simplex_t *simplex, - ccd_pt_t *pt, ccd_pt_el_t **nearest); - -/** Transforms simplex to polytope, two vertices required */ -static int simplexToPolytope2(const void *obj1, const void *obj2, - const ccd_t *ccd, - const ccd_simplex_t *simplex, - ccd_pt_t *pt, ccd_pt_el_t **nearest); - -/** Expands polytope using new vertex v. - * Return 0 on success, -2 on memory allocation failure.*/ -static int expandPolytope(ccd_pt_t *pt, ccd_pt_el_t *el, - const ccd_support_t *newv); - -/** Finds next support point (at stores it in out argument). - * Returns 0 on success, -1 otherwise */ -static int nextSupport(const void *obj1, const void *obj2, const ccd_t *ccd, - const ccd_pt_el_t *el, - ccd_support_t *out); - - - -void ccdFirstDirDefault(const void *o1, const void *o2, ccd_vec3_t *dir) -{ - (void)(o1); - (void)(o2); - - ccdVec3Set(dir, CCD_ONE, CCD_ZERO, CCD_ZERO); -} - -int ccdGJKIntersect(const void *obj1, const void *obj2, const ccd_t *ccd) -{ - ccd_simplex_t simplex; - return __ccdGJK(obj1, obj2, ccd, &simplex) == 0; -} - -int ccdGJKSeparate(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_vec3_t *sep) -{ - ccd_pt_t polytope; - ccd_pt_el_t *nearest; - int ret; - - ccdPtInit(&polytope); - - ret = __ccdGJKEPA(obj1, obj2, ccd, &polytope, &nearest); - - // set separation vector - if (nearest) - ccdVec3Copy(sep, &nearest->witness); - - ccdPtDestroy(&polytope); - - return ret; -} - - -static int penEPAPosCmp(const void *a, const void *b) -{ - ccd_pt_vertex_t *v1, *v2; - v1 = *(ccd_pt_vertex_t **)a; - v2 = *(ccd_pt_vertex_t **)b; - - if (ccdEq(v1->dist, v2->dist)){ - return 0; - }else if (v1->dist < v2->dist){ - return -1; - }else{ - return 1; - } -} - -static int penEPAPos(const ccd_pt_t *pt, const ccd_pt_el_t * nearest, - ccd_vec3_t *pos) -{ - (void)(nearest); - - ccd_pt_vertex_t *v; - ccd_pt_vertex_t **vs; - size_t i, len; - ccd_real_t scale; - - // compute median - len = 0; - ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){ - len++; - } - - vs = CCD_ALLOC_ARR(ccd_pt_vertex_t *, len); - if (vs == NULL) - return -1; - - i = 0; - ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){ - vs[i++] = v; - } - - qsort(vs, len, sizeof(ccd_pt_vertex_t *), penEPAPosCmp); - - ccdVec3Set(pos, CCD_ZERO, CCD_ZERO, CCD_ZERO); - scale = CCD_ZERO; - if (len % 2 == 1) - len++; - - for (i = 0; i < len / 2; i++){ - ccdVec3Add(pos, &vs[i]->v.v1); - ccdVec3Add(pos, &vs[i]->v.v2); - scale += CCD_REAL(2.); - } - ccdVec3Scale(pos, CCD_ONE / scale); - - free(vs); - - return 0; -} - -int ccdGJKPenetration(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos) -{ - ccd_pt_t polytope; - ccd_pt_el_t *nearest; - int ret; - - ccdPtInit(&polytope); - - ret = __ccdGJKEPA(obj1, obj2, ccd, &polytope, &nearest); - - // set separation vector - if (ret == 0 && nearest){ - // compute depth of penetration - *depth = CCD_SQRT(nearest->dist); - - // store normalized direction vector - ccdVec3Copy(dir, &nearest->witness); - ccdVec3Normalize(dir); - - // compute position - if (penEPAPos(&polytope, nearest, pos) != 0){ - ccdPtDestroy(&polytope); - return -2; - } - } - - ccdPtDestroy(&polytope); - - return ret; -} - - -static int __ccdGJK(const void *obj1, const void *obj2, - const ccd_t *ccd, ccd_simplex_t *simplex) -{ - unsigned long iterations; - ccd_vec3_t dir; // direction vector - ccd_support_t last; // last support point - int do_simplex_res; - - // initialize simplex struct - ccdSimplexInit(simplex); - - // get first direction - ccd->first_dir(obj1, obj2, &dir); - // get first support point - __ccdSupport(obj1, obj2, &dir, ccd, &last); - // and add this point to simplex as last one - ccdSimplexAdd(simplex, &last); - - // set up direction vector to as (O - last) which is exactly -last - ccdVec3Copy(&dir, &last.v); - ccdVec3Scale(&dir, -CCD_ONE); - - // start iterations - for (iterations = 0UL; iterations < ccd->max_iterations; ++iterations) { - // obtain support point - __ccdSupport(obj1, obj2, &dir, ccd, &last); - - // check if farthest point in Minkowski difference in direction dir - // isn't somewhere before origin (the test on negative dot product) - // - because if it is, objects are not intersecting at all. - if (ccdVec3Dot(&last.v, &dir) < CCD_ZERO){ - return -1; // intersection not found - } - - // add last support vector to simplex - ccdSimplexAdd(simplex, &last); - - // if doSimplex returns 1 if objects intersect, -1 if objects don't - // intersect and 0 if algorithm should continue - do_simplex_res = doSimplex(simplex, &dir); - if (do_simplex_res == 1){ - return 0; // intersection found - }else if (do_simplex_res == -1){ - return -1; // intersection not found - } - - if (ccdIsZero(ccdVec3Len2(&dir))){ - return -1; // intersection not found - } - } - - // intersection wasn't found - return -1; -} - -static int __ccdGJKEPA(const void *obj1, const void *obj2, - const ccd_t *ccd, - ccd_pt_t *polytope, ccd_pt_el_t **nearest) -{ - ccd_simplex_t simplex; - ccd_support_t supp; // support point - int ret, size; - - *nearest = NULL; - - // run GJK and obtain terminal simplex - ret = __ccdGJK(obj1, obj2, ccd, &simplex); - if (ret != 0) - return -1; - - // transform simplex to polytope - simplex won't be used anymore - size = ccdSimplexSize(&simplex); - if (size == 4){ - ret = simplexToPolytope4(obj1, obj2, ccd, &simplex, polytope, nearest); - }else if (size == 3){ - ret = simplexToPolytope3(obj1, obj2, ccd, &simplex, polytope, nearest); - }else{ // size == 2 - ret = simplexToPolytope2(obj1, obj2, ccd, &simplex, polytope, nearest); - } - - if (ret == -1){ - // touching contact - return 0; - }else if (ret == -2){ - // failed memory allocation - return -2; - } - - - while (1){ - // get triangle nearest to origin - *nearest = ccdPtNearest(polytope); - - // get next support point - if (nextSupport(obj1, obj2, ccd, *nearest, &supp) != 0) - break; - - // expand nearest triangle using new point - supp - if (expandPolytope(polytope, *nearest, &supp) != 0) - return -2; - } - - return 0; -} - - - -static int doSimplex2(ccd_simplex_t *simplex, ccd_vec3_t *dir) -{ - const ccd_support_t *A, *B; - ccd_vec3_t AB, AO, tmp; - ccd_real_t dot; - - // get last added as A - A = ccdSimplexLast(simplex); - // get the other point - B = ccdSimplexPoint(simplex, 0); - // compute AB oriented segment - ccdVec3Sub2(&AB, &B->v, &A->v); - // compute AO vector - ccdVec3Copy(&AO, &A->v); - ccdVec3Scale(&AO, -CCD_ONE); - - // dot product AB . AO - dot = ccdVec3Dot(&AB, &AO); - - // check if origin doesn't lie on AB segment - ccdVec3Cross(&tmp, &AB, &AO); - if (ccdIsZero(ccdVec3Len2(&tmp)) && dot > CCD_ZERO){ - return 1; - } - - // check if origin is in area where AB segment is - if (ccdIsZero(dot) || dot < CCD_ZERO){ - // origin is in outside are of A - ccdSimplexSet(simplex, 0, A); - ccdSimplexSetSize(simplex, 1); - ccdVec3Copy(dir, &AO); - }else{ - // origin is in area where AB segment is - - // keep simplex untouched and set direction to - // AB x AO x AB - tripleCross(&AB, &AO, &AB, dir); - } - - return 0; -} - -static int doSimplex3(ccd_simplex_t *simplex, ccd_vec3_t *dir) -{ - const ccd_support_t *A, *B, *C; - ccd_vec3_t AO, AB, AC, ABC, tmp; - ccd_real_t dot, dist; - - // get last added as A - A = ccdSimplexLast(simplex); - // get the other points - B = ccdSimplexPoint(simplex, 1); - C = ccdSimplexPoint(simplex, 0); - - // check touching contact - dist = ccdVec3PointTriDist2(ccd_vec3_origin, &A->v, &B->v, &C->v, NULL); - if (ccdIsZero(dist)){ - return 1; - } - - // check if triangle is really triangle (has area > 0) - // if not simplex can't be expanded and thus no itersection is found - if (ccdVec3Eq(&A->v, &B->v) || ccdVec3Eq(&A->v, &C->v)){ - return -1; - } - - // compute AO vector - ccdVec3Copy(&AO, &A->v); - ccdVec3Scale(&AO, -CCD_ONE); - - // compute AB and AC segments and ABC vector (perpendircular to triangle) - ccdVec3Sub2(&AB, &B->v, &A->v); - ccdVec3Sub2(&AC, &C->v, &A->v); - ccdVec3Cross(&ABC, &AB, &AC); - - ccdVec3Cross(&tmp, &ABC, &AC); - dot = ccdVec3Dot(&tmp, &AO); - if (ccdIsZero(dot) || dot > CCD_ZERO){ - dot = ccdVec3Dot(&AC, &AO); - if (ccdIsZero(dot) || dot > CCD_ZERO){ - // C is already in place - ccdSimplexSet(simplex, 1, A); - ccdSimplexSetSize(simplex, 2); - tripleCross(&AC, &AO, &AC, dir); - }else{ -ccd_do_simplex3_45: - dot = ccdVec3Dot(&AB, &AO); - if (ccdIsZero(dot) || dot > CCD_ZERO){ - ccdSimplexSet(simplex, 0, B); - ccdSimplexSet(simplex, 1, A); - ccdSimplexSetSize(simplex, 2); - tripleCross(&AB, &AO, &AB, dir); - }else{ - ccdSimplexSet(simplex, 0, A); - ccdSimplexSetSize(simplex, 1); - ccdVec3Copy(dir, &AO); - } - } - }else{ - ccdVec3Cross(&tmp, &AB, &ABC); - dot = ccdVec3Dot(&tmp, &AO); - if (ccdIsZero(dot) || dot > CCD_ZERO){ - goto ccd_do_simplex3_45; - }else{ - dot = ccdVec3Dot(&ABC, &AO); - if (ccdIsZero(dot) || dot > CCD_ZERO){ - ccdVec3Copy(dir, &ABC); - }else{ - ccd_support_t Ctmp; - ccdSupportCopy(&Ctmp, C); - ccdSimplexSet(simplex, 0, B); - ccdSimplexSet(simplex, 1, &Ctmp); - - ccdVec3Copy(dir, &ABC); - ccdVec3Scale(dir, -CCD_ONE); - } - } - } - - return 0; -} - -static int doSimplex4(ccd_simplex_t *simplex, ccd_vec3_t *dir) -{ - const ccd_support_t *A, *B, *C, *D; - ccd_vec3_t AO, AB, AC, AD, ABC, ACD, ADB; - int B_on_ACD, C_on_ADB, D_on_ABC; - int AB_O, AC_O, AD_O; - ccd_real_t dist; - - // get last added as A - A = ccdSimplexLast(simplex); - // get the other points - B = ccdSimplexPoint(simplex, 2); - C = ccdSimplexPoint(simplex, 1); - D = ccdSimplexPoint(simplex, 0); - - // check if tetrahedron is really tetrahedron (has volume > 0) - // if it is not simplex can't be expanded and thus no intersection is - // found - dist = ccdVec3PointTriDist2(&A->v, &B->v, &C->v, &D->v, NULL); - if (ccdIsZero(dist)){ - return -1; - } - - // check if origin lies on some of tetrahedron's face - if so objects - // intersect - dist = ccdVec3PointTriDist2(ccd_vec3_origin, &A->v, &B->v, &C->v, NULL); - if (ccdIsZero(dist)) - return 1; - dist = ccdVec3PointTriDist2(ccd_vec3_origin, &A->v, &C->v, &D->v, NULL); - if (ccdIsZero(dist)) - return 1; - dist = ccdVec3PointTriDist2(ccd_vec3_origin, &A->v, &B->v, &D->v, NULL); - if (ccdIsZero(dist)) - return 1; - dist = ccdVec3PointTriDist2(ccd_vec3_origin, &B->v, &C->v, &D->v, NULL); - if (ccdIsZero(dist)) - return 1; - - // compute AO, AB, AC, AD segments and ABC, ACD, ADB normal vectors - ccdVec3Copy(&AO, &A->v); - ccdVec3Scale(&AO, -CCD_ONE); - ccdVec3Sub2(&AB, &B->v, &A->v); - ccdVec3Sub2(&AC, &C->v, &A->v); - ccdVec3Sub2(&AD, &D->v, &A->v); - ccdVec3Cross(&ABC, &AB, &AC); - ccdVec3Cross(&ACD, &AC, &AD); - ccdVec3Cross(&ADB, &AD, &AB); - - // side (positive or negative) of B, C, D relative to planes ACD, ADB - // and ABC respectively - B_on_ACD = ccdSign(ccdVec3Dot(&ACD, &AB)); - C_on_ADB = ccdSign(ccdVec3Dot(&ADB, &AC)); - D_on_ABC = ccdSign(ccdVec3Dot(&ABC, &AD)); - - // whether origin is on same side of ACD, ADB, ABC as B, C, D - // respectively - AB_O = ccdSign(ccdVec3Dot(&ACD, &AO)) == B_on_ACD; - AC_O = ccdSign(ccdVec3Dot(&ADB, &AO)) == C_on_ADB; - AD_O = ccdSign(ccdVec3Dot(&ABC, &AO)) == D_on_ABC; - - if (AB_O && AC_O && AD_O){ - // origin is in tetrahedron - return 1; - - // rearrange simplex to triangle and call doSimplex3() - }else if (!AB_O){ - // B is farthest from the origin among all of the tetrahedron's - // points, so remove it from the list and go on with the triangle - // case - - // D and C are in place - ccdSimplexSet(simplex, 2, A); - ccdSimplexSetSize(simplex, 3); - }else if (!AC_O){ - // C is farthest - ccdSimplexSet(simplex, 1, D); - ccdSimplexSet(simplex, 0, B); - ccdSimplexSet(simplex, 2, A); - ccdSimplexSetSize(simplex, 3); - }else{ // (!AD_O) - ccdSimplexSet(simplex, 0, C); - ccdSimplexSet(simplex, 1, B); - ccdSimplexSet(simplex, 2, A); - ccdSimplexSetSize(simplex, 3); - } - - return doSimplex3(simplex, dir); -} - -static int doSimplex(ccd_simplex_t *simplex, ccd_vec3_t *dir) -{ - if (ccdSimplexSize(simplex) == 2){ - // simplex contains segment only one segment - return doSimplex2(simplex, dir); - }else if (ccdSimplexSize(simplex) == 3){ - // simplex contains triangle - return doSimplex3(simplex, dir); - }else{ // ccdSimplexSize(simplex) == 4 - // tetrahedron - this is the only shape which can encapsule origin - // so doSimplex4() also contains test on it - return doSimplex4(simplex, dir); - } -} - - -_ccd_inline void tripleCross(const ccd_vec3_t *a, const ccd_vec3_t *b, - const ccd_vec3_t *c, ccd_vec3_t *d) -{ - ccd_vec3_t e; - ccdVec3Cross(&e, a, b); - ccdVec3Cross(d, &e, c); -} - - - -/** Transforms simplex to polytope. It is assumed that simplex has 4 - * vertices! */ -static int simplexToPolytope4(const void *obj1, const void *obj2, - const ccd_t *ccd, - ccd_simplex_t *simplex, - ccd_pt_t *pt, ccd_pt_el_t **nearest) -{ - const ccd_support_t *a, *b, *c, *d; - int use_polytope3; - ccd_real_t dist; - ccd_pt_vertex_t *v[4]; - ccd_pt_edge_t *e[6]; - size_t i; - - a = ccdSimplexPoint(simplex, 0); - b = ccdSimplexPoint(simplex, 1); - c = ccdSimplexPoint(simplex, 2); - d = ccdSimplexPoint(simplex, 3); - - // check if origin lies on some of tetrahedron's face - if so use - // simplexToPolytope3() - use_polytope3 = 0; - dist = ccdVec3PointTriDist2(ccd_vec3_origin, &a->v, &b->v, &c->v, NULL); - if (ccdIsZero(dist)){ - use_polytope3 = 1; - } - dist = ccdVec3PointTriDist2(ccd_vec3_origin, &a->v, &c->v, &d->v, NULL); - if (ccdIsZero(dist)){ - use_polytope3 = 1; - ccdSimplexSet(simplex, 1, c); - ccdSimplexSet(simplex, 2, d); - } - dist = ccdVec3PointTriDist2(ccd_vec3_origin, &a->v, &b->v, &d->v, NULL); - if (ccdIsZero(dist)){ - use_polytope3 = 1; - ccdSimplexSet(simplex, 2, d); - } - dist = ccdVec3PointTriDist2(ccd_vec3_origin, &b->v, &c->v, &d->v, NULL); - if (ccdIsZero(dist)){ - use_polytope3 = 1; - ccdSimplexSet(simplex, 0, b); - ccdSimplexSet(simplex, 1, c); - ccdSimplexSet(simplex, 2, d); - } - - if (use_polytope3){ - ccdSimplexSetSize(simplex, 3); - return simplexToPolytope3(obj1, obj2, ccd, simplex, pt, nearest); - } - - // no touching contact - simply create tetrahedron - for (i = 0; i < 4; i++){ - v[i] = ccdPtAddVertex(pt, ccdSimplexPoint(simplex, (int)i)); - } - - e[0] = ccdPtAddEdge(pt, v[0], v[1]); - e[1] = ccdPtAddEdge(pt, v[1], v[2]); - e[2] = ccdPtAddEdge(pt, v[2], v[0]); - e[3] = ccdPtAddEdge(pt, v[3], v[0]); - e[4] = ccdPtAddEdge(pt, v[3], v[1]); - e[5] = ccdPtAddEdge(pt, v[3], v[2]); - - // ccdPtAdd*() functions return NULL either if the memory allocation - // failed of if any of the input pointers are NULL, so the bad - // allocation can be checked by the last calls of ccdPtAddFace() - // because the rest of the bad allocations eventually "bubble up" here - if (ccdPtAddFace(pt, e[0], e[1], e[2]) == NULL - || ccdPtAddFace(pt, e[3], e[4], e[0]) == NULL - || ccdPtAddFace(pt, e[4], e[5], e[1]) == NULL - || ccdPtAddFace(pt, e[5], e[3], e[2]) == NULL){ - return -2; - } - - return 0; -} - -/** Transforms simplex to polytope, three vertices required */ -static int simplexToPolytope3(const void *obj1, const void *obj2, - const ccd_t *ccd, - const ccd_simplex_t *simplex, - ccd_pt_t *pt, ccd_pt_el_t **nearest) -{ - const ccd_support_t *a, *b, *c; - ccd_support_t d, d2; - ccd_vec3_t ab, ac, dir; - ccd_pt_vertex_t *v[5]; - ccd_pt_edge_t *e[9]; - ccd_real_t dist, dist2; - - *nearest = NULL; - - a = ccdSimplexPoint(simplex, 0); - b = ccdSimplexPoint(simplex, 1); - c = ccdSimplexPoint(simplex, 2); - - // If only one triangle left from previous GJK run origin lies on this - // triangle. So it is necessary to expand triangle into two - // tetrahedrons connected with base (which is exactly abc triangle). - - // get next support point in direction of normal of triangle - ccdVec3Sub2(&ab, &b->v, &a->v); - ccdVec3Sub2(&ac, &c->v, &a->v); - ccdVec3Cross(&dir, &ab, &ac); - __ccdSupport(obj1, obj2, &dir, ccd, &d); - dist = ccdVec3PointTriDist2(&d.v, &a->v, &b->v, &c->v, NULL); - - // and second one take in opposite direction - ccdVec3Scale(&dir, -CCD_ONE); - __ccdSupport(obj1, obj2, &dir, ccd, &d2); - dist2 = ccdVec3PointTriDist2(&d2.v, &a->v, &b->v, &c->v, NULL); - - // check if face isn't already on edge of minkowski sum and thus we - // have touching contact - if (ccdIsZero(dist) || ccdIsZero(dist2)){ - v[0] = ccdPtAddVertex(pt, a); - v[1] = ccdPtAddVertex(pt, b); - v[2] = ccdPtAddVertex(pt, c); - e[0] = ccdPtAddEdge(pt, v[0], v[1]); - e[1] = ccdPtAddEdge(pt, v[1], v[2]); - e[2] = ccdPtAddEdge(pt, v[2], v[0]); - *nearest = (ccd_pt_el_t *)ccdPtAddFace(pt, e[0], e[1], e[2]); - if (*nearest == NULL) - return -2; - - return -1; - } - - // form polyhedron - v[0] = ccdPtAddVertex(pt, a); - v[1] = ccdPtAddVertex(pt, b); - v[2] = ccdPtAddVertex(pt, c); - v[3] = ccdPtAddVertex(pt, &d); - v[4] = ccdPtAddVertex(pt, &d2); - - e[0] = ccdPtAddEdge(pt, v[0], v[1]); - e[1] = ccdPtAddEdge(pt, v[1], v[2]); - e[2] = ccdPtAddEdge(pt, v[2], v[0]); - - e[3] = ccdPtAddEdge(pt, v[3], v[0]); - e[4] = ccdPtAddEdge(pt, v[3], v[1]); - e[5] = ccdPtAddEdge(pt, v[3], v[2]); - - e[6] = ccdPtAddEdge(pt, v[4], v[0]); - e[7] = ccdPtAddEdge(pt, v[4], v[1]); - e[8] = ccdPtAddEdge(pt, v[4], v[2]); - - if (ccdPtAddFace(pt, e[3], e[4], e[0]) == NULL - || ccdPtAddFace(pt, e[4], e[5], e[1]) == NULL - || ccdPtAddFace(pt, e[5], e[3], e[2]) == NULL - - || ccdPtAddFace(pt, e[6], e[7], e[0]) == NULL - || ccdPtAddFace(pt, e[7], e[8], e[1]) == NULL - || ccdPtAddFace(pt, e[8], e[6], e[2]) == NULL){ - return -2; - } - - return 0; -} - -/** Transforms simplex to polytope, two vertices required */ -static int simplexToPolytope2(const void *obj1, const void *obj2, - const ccd_t *ccd, - const ccd_simplex_t *simplex, - ccd_pt_t *pt, ccd_pt_el_t **nearest) -{ - const ccd_support_t *a, *b; - ccd_vec3_t ab, ac, dir; - ccd_support_t supp[4]; - ccd_pt_vertex_t *v[6]; - ccd_pt_edge_t *e[12]; - size_t i; - int found; - - a = ccdSimplexPoint(simplex, 0); - b = ccdSimplexPoint(simplex, 1); - - // This situation is a bit tricky. If only one segment comes from - // previous run of GJK - it means that either this segment is on - // minkowski edge (and thus we have touch contact) or it it isn't and - // therefore segment is somewhere *inside* minkowski sum and it *must* - // be possible to fully enclose this segment with polyhedron formed by - // at least 8 triangle faces. - - // get first support point (any) - found = 0; - for (i = 0; i < ccd_points_on_sphere_len; i++){ - __ccdSupport(obj1, obj2, &ccd_points_on_sphere[i], ccd, &supp[0]); - if (!ccdVec3Eq(&a->v, &supp[0].v) && !ccdVec3Eq(&b->v, &supp[0].v)){ - found = 1; - break; - } - } - if (!found) - goto simplexToPolytope2_touching_contact; - - // get second support point in opposite direction than supp[0] - ccdVec3Copy(&dir, &supp[0].v); - ccdVec3Scale(&dir, -CCD_ONE); - __ccdSupport(obj1, obj2, &dir, ccd, &supp[1]); - if (ccdVec3Eq(&a->v, &supp[1].v) || ccdVec3Eq(&b->v, &supp[1].v)) - goto simplexToPolytope2_touching_contact; - - // next will be in direction of normal of triangle a,supp[0],supp[1] - ccdVec3Sub2(&ab, &supp[0].v, &a->v); - ccdVec3Sub2(&ac, &supp[1].v, &a->v); - ccdVec3Cross(&dir, &ab, &ac); - __ccdSupport(obj1, obj2, &dir, ccd, &supp[2]); - if (ccdVec3Eq(&a->v, &supp[2].v) || ccdVec3Eq(&b->v, &supp[2].v)) - goto simplexToPolytope2_touching_contact; - - // and last one will be in opposite direction - ccdVec3Scale(&dir, -CCD_ONE); - __ccdSupport(obj1, obj2, &dir, ccd, &supp[3]); - if (ccdVec3Eq(&a->v, &supp[3].v) || ccdVec3Eq(&b->v, &supp[3].v)) - goto simplexToPolytope2_touching_contact; - - goto simplexToPolytope2_not_touching_contact; -simplexToPolytope2_touching_contact: - v[0] = ccdPtAddVertex(pt, a); - v[1] = ccdPtAddVertex(pt, b); - *nearest = (ccd_pt_el_t *)ccdPtAddEdge(pt, v[0], v[1]); - if (*nearest == NULL) - return -2; - - return -1; - -simplexToPolytope2_not_touching_contact: - // form polyhedron - v[0] = ccdPtAddVertex(pt, a); - v[1] = ccdPtAddVertex(pt, &supp[0]); - v[2] = ccdPtAddVertex(pt, b); - v[3] = ccdPtAddVertex(pt, &supp[1]); - v[4] = ccdPtAddVertex(pt, &supp[2]); - v[5] = ccdPtAddVertex(pt, &supp[3]); - - e[0] = ccdPtAddEdge(pt, v[0], v[1]); - e[1] = ccdPtAddEdge(pt, v[1], v[2]); - e[2] = ccdPtAddEdge(pt, v[2], v[3]); - e[3] = ccdPtAddEdge(pt, v[3], v[0]); - - e[4] = ccdPtAddEdge(pt, v[4], v[0]); - e[5] = ccdPtAddEdge(pt, v[4], v[1]); - e[6] = ccdPtAddEdge(pt, v[4], v[2]); - e[7] = ccdPtAddEdge(pt, v[4], v[3]); - - e[8] = ccdPtAddEdge(pt, v[5], v[0]); - e[9] = ccdPtAddEdge(pt, v[5], v[1]); - e[10] = ccdPtAddEdge(pt, v[5], v[2]); - e[11] = ccdPtAddEdge(pt, v[5], v[3]); - - if (ccdPtAddFace(pt, e[4], e[5], e[0]) == NULL - || ccdPtAddFace(pt, e[5], e[6], e[1]) == NULL - || ccdPtAddFace(pt, e[6], e[7], e[2]) == NULL - || ccdPtAddFace(pt, e[7], e[4], e[3]) == NULL - - || ccdPtAddFace(pt, e[8], e[9], e[0]) == NULL - || ccdPtAddFace(pt, e[9], e[10], e[1]) == NULL - || ccdPtAddFace(pt, e[10], e[11], e[2]) == NULL - || ccdPtAddFace(pt, e[11], e[8], e[3]) == NULL){ - return -2; - } - - return 0; -} - -/** Expands polytope's tri by new vertex v. Triangle tri is replaced by - * three triangles each with one vertex in v. */ -static int expandPolytope(ccd_pt_t *pt, ccd_pt_el_t *el, - const ccd_support_t *newv) -{ - ccd_pt_vertex_t *v[5]; - ccd_pt_edge_t *e[8]; - ccd_pt_face_t *f[2]; - - - // element can be either segment or triangle - if (el->type == CCD_PT_EDGE){ - // In this case, segment should be replaced by new point. - // Simpliest case is when segment stands alone and in this case - // this segment is replaced by two other segments both connected to - // newv. - // Segment can be also connected to max two faces and in that case - // each face must be replaced by two other faces. To do this - // correctly it is necessary to have correctly ordered edges and - // vertices which is exactly what is done in following code. - // - - ccdPtEdgeVertices((const ccd_pt_edge_t *)el, &v[0], &v[2]); - - ccdPtEdgeFaces((ccd_pt_edge_t *)el, &f[0], &f[1]); - - if (f[0]){ - ccdPtFaceEdges(f[0], &e[0], &e[1], &e[2]); - if (e[0] == (ccd_pt_edge_t *)el){ - e[0] = e[2]; - }else if (e[1] == (ccd_pt_edge_t *)el){ - e[1] = e[2]; - } - ccdPtEdgeVertices(e[0], &v[1], &v[3]); - if (v[1] != v[0] && v[3] != v[0]){ - e[2] = e[0]; - e[0] = e[1]; - e[1] = e[2]; - if (v[1] == v[2]) - v[1] = v[3]; - }else{ - if (v[1] == v[0]) - v[1] = v[3]; - } - - if (f[1]){ - ccdPtFaceEdges(f[1], &e[2], &e[3], &e[4]); - if (e[2] == (ccd_pt_edge_t *)el){ - e[2] = e[4]; - }else if (e[3] == (ccd_pt_edge_t *)el){ - e[3] = e[4]; - } - ccdPtEdgeVertices(e[2], &v[3], &v[4]); - if (v[3] != v[2] && v[4] != v[2]){ - e[4] = e[2]; - e[2] = e[3]; - e[3] = e[4]; - if (v[3] == v[0]) - v[3] = v[4]; - }else{ - if (v[3] == v[2]) - v[3] = v[4]; - } - } - - - v[4] = ccdPtAddVertex(pt, newv); - - ccdPtDelFace(pt, f[0]); - if (f[1]){ - ccdPtDelFace(pt, f[1]); - ccdPtDelEdge(pt, (ccd_pt_edge_t *)el); - } - - e[4] = ccdPtAddEdge(pt, v[4], v[2]); - e[5] = ccdPtAddEdge(pt, v[4], v[0]); - e[6] = ccdPtAddEdge(pt, v[4], v[1]); - if (f[1]) - e[7] = ccdPtAddEdge(pt, v[4], v[3]); - - - if (ccdPtAddFace(pt, e[1], e[4], e[6]) == NULL - || ccdPtAddFace(pt, e[0], e[6], e[5]) == NULL){ - return -2; - } - - if (f[1]){ - if (ccdPtAddFace(pt, e[3], e[5], e[7]) == NULL - || ccdPtAddFace(pt, e[4], e[7], e[2]) == NULL){ - return -2; - } - }else{ - if (ccdPtAddFace(pt, e[4], e[5], (ccd_pt_edge_t *)el) == NULL) - return -2; - } - } - }else{ // el->type == CCD_PT_FACE - // replace triangle by tetrahedron without base (base would be the - // triangle that will be removed) - - // get triplet of surrounding edges and vertices of triangle face - ccdPtFaceEdges((const ccd_pt_face_t *)el, &e[0], &e[1], &e[2]); - ccdPtEdgeVertices(e[0], &v[0], &v[1]); - ccdPtEdgeVertices(e[1], &v[2], &v[3]); - - // following code sorts edges to have e[0] between vertices 0-1, - // e[1] between 1-2 and e[2] between 2-0 - if (v[2] != v[1] && v[3] != v[1]){ - // swap e[1] and e[2] - e[3] = e[1]; - e[1] = e[2]; - e[2] = e[3]; - } - if (v[3] != v[0] && v[3] != v[1]) - v[2] = v[3]; - - // remove triangle face - ccdPtDelFace(pt, (ccd_pt_face_t *)el); - - // expand triangle to tetrahedron - v[3] = ccdPtAddVertex(pt, newv); - e[3] = ccdPtAddEdge(pt, v[3], v[0]); - e[4] = ccdPtAddEdge(pt, v[3], v[1]); - e[5] = ccdPtAddEdge(pt, v[3], v[2]); - - if (ccdPtAddFace(pt, e[3], e[4], e[0]) == NULL - || ccdPtAddFace(pt, e[4], e[5], e[1]) == NULL - || ccdPtAddFace(pt, e[5], e[3], e[2]) == NULL){ - return -2; - } - } - - return 0; -} - -/** Finds next support point (and stores it in out argument). - * Returns 0 on success, -1 otherwise */ -static int nextSupport(const void *obj1, const void *obj2, const ccd_t *ccd, - const ccd_pt_el_t *el, - ccd_support_t *out) -{ - ccd_vec3_t *a, *b, *c; - ccd_real_t dist; - - if (el->type == CCD_PT_VERTEX) - return -1; - - // touch contact - if (ccdIsZero(el->dist)) - return -1; - - __ccdSupport(obj1, obj2, &el->witness, ccd, out); - - // Compute dist of support point along element witness point direction - // so we can determine whether we expanded a polytope surrounding the - // origin a bit. - dist = ccdVec3Dot(&out->v, &el->witness); - - if (dist - el->dist < ccd->epa_tolerance) - return -1; - - if (el->type == CCD_PT_EDGE){ - // fetch end points of edge - ccdPtEdgeVec3((ccd_pt_edge_t *)el, &a, &b); - - // get distance from segment - dist = ccdVec3PointSegmentDist2(&out->v, a, b, NULL); - }else{ // el->type == CCD_PT_FACE - // fetch vertices of triangle face - ccdPtFaceVec3((ccd_pt_face_t *)el, &a, &b, &c); - - // check if new point can significantly expand polytope - dist = ccdVec3PointTriDist2(&out->v, a, b, c, NULL); - } - - if (dist < ccd->epa_tolerance) - return -1; - - return 0; -} diff --git a/src/pe/extern/libccd/ccd/ccd.h b/src/pe/extern/libccd/ccd/ccd.h deleted file mode 100644 index fb8df75a081c6484c7f9445adb82c2b4f30fe786..0000000000000000000000000000000000000000 --- a/src/pe/extern/libccd/ccd/ccd.h +++ /dev/null @@ -1,154 +0,0 @@ -/*** - * libccd - * --------------------------------- - * Copyright (c)2010,2011 Daniel Fiser <danfis@danfis.cz> - * - * - * This file is part of libccd. - * - * Distributed under the OSI-approved BSD License (the "License"); - * see accompanying file BDS-LICENSE for details or see - * <http://www.opensource.org/licenses/bsd-license.php>. - * - * This software is distributed WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the License for more information. - */ - -#ifndef __CCD_H__ -#define __CCD_H__ - -#include <ccd/vec3.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** - * Type of *support* function that takes pointer to 3D object and direction - * and returns (via vec argument) furthest point from object in specified - * direction. - */ -typedef void (*ccd_support_fn)(const void *obj, const ccd_vec3_t *dir, - ccd_vec3_t *vec); - -/** - * Returns (via dir argument) first direction vector that will be used in - * initialization of algorithm. - */ -typedef void (*ccd_first_dir_fn)(const void *obj1, const void *obj2, - ccd_vec3_t *dir); - - -/** - * Returns (via center argument) geometric center (some point near center) - * of given object. - */ -typedef void (*ccd_center_fn)(const void *obj1, ccd_vec3_t *center); - -/** - * Main structure of CCD algorithm. - */ -struct _ccd_t { - ccd_first_dir_fn first_dir; //!< Returns initial direction where first - //!< support point will be searched - ccd_support_fn support1; //!< Function that returns support point of - //!< first object - ccd_support_fn support2; //!< Function that returns support point of - //!< second object - - ccd_center_fn center1; //!< Function that returns geometric center of - //!< first object - ccd_center_fn center2; //!< Function that returns geometric center of - //!< second object - - unsigned long max_iterations; //!< Maximal number of iterations - ccd_real_t epa_tolerance; - ccd_real_t mpr_tolerance; //!< Boundary tolerance for MPR algorithm - ccd_real_t dist_tolerance; -}; -typedef struct _ccd_t ccd_t; - -/** - * Default first direction. - */ -_ccd_export void ccdFirstDirDefault(const void *o1, const void *o2, - ccd_vec3_t *dir); - -#define CCD_INIT(ccd) \ - do { \ - (ccd)->first_dir = ccdFirstDirDefault; \ - (ccd)->support1 = NULL; \ - (ccd)->support2 = NULL; \ - (ccd)->center1 = NULL; \ - (ccd)->center2 = NULL; \ - \ - (ccd)->max_iterations = (unsigned long)-1; \ - (ccd)->epa_tolerance = CCD_REAL(0.0001); \ - (ccd)->mpr_tolerance = CCD_REAL(0.0001); \ - (ccd)->dist_tolerance = CCD_REAL(1E-6); \ - } while(0) - - -/** - * Returns true if two given objects interest. - */ -_ccd_export int ccdGJKIntersect(const void *obj1, const void *obj2, - const ccd_t *ccd); - -/** - * This function computes separation vector of two objects. Separation - * vector is minimal translation of obj2 to get obj1 and obj2 speparated - * (without intersection). - * Returns 0 if obj1 and obj2 intersect and sep is filled with translation - * vector. If obj1 and obj2 don't intersect -1 is returned. - * If memory allocation fails -2 is returned. - */ -_ccd_export int ccdGJKSeparate(const void *obj1, const void *obj2, - const ccd_t *ccd, ccd_vec3_t *sep); - -/** - * Computes penetration of obj2 into obj1. - * Depth of penetration, direction and position is returned. It means that - * if obj2 is translated by distance depth in direction dir objects will - * have touching contact, pos should be position in global coordinates - * where force should take a place. - * - * CCD+EPA algorithm is used. - * - * Returns 0 if obj1 and obj2 intersect and depth, dir and pos are filled - * if given non-NULL pointers. - * If obj1 and obj2 don't intersect -1 is returned. - * If memory allocation fails -2 is returned. - */ -_ccd_export int ccdGJKPenetration(const void *obj1, const void *obj2, - const ccd_t *ccd, ccd_real_t *depth, - ccd_vec3_t *dir, ccd_vec3_t *pos); - -/** - * Returns true if two given objects intersect - MPR algorithm is used. - */ -_ccd_export int ccdMPRIntersect(const void *obj1, const void *obj2, - const ccd_t *ccd); - -/** - * Computes penetration of obj2 into obj1. - * Depth of penetration, direction and position is returned, i.e. if obj2 - * is translated by computed depth in resulting direction obj1 and obj2 - * would have touching contact. Position is point in global coordinates - * where force should be take a place. - * - * Minkowski Portal Refinement algorithm is used (MPR, a.k.a. XenoCollide, - * see Game Programming Gem 7). - * - * Returns 0 if obj1 and obj2 intersect, otherwise -1 is returned. - */ -_ccd_export int ccdMPRPenetration(const void *obj1, const void *obj2, - const ccd_t *ccd, ccd_real_t *depth, - ccd_vec3_t *dir, ccd_vec3_t *pos); - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif /* __CCD_H__ */ diff --git a/src/pe/extern/libccd/ccd/compiler.h b/src/pe/extern/libccd/ccd/compiler.h deleted file mode 100644 index b022e26e47875e9f2392b82adfadbd430d5b69b6..0000000000000000000000000000000000000000 --- a/src/pe/extern/libccd/ccd/compiler.h +++ /dev/null @@ -1,83 +0,0 @@ -/*** - * libccd - * --------------------------------- - * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> - * - * - * This file is part of libccd. - * - * Distributed under the OSI-approved BSD License (the "License"); - * see accompanying file BDS-LICENSE for details or see - * <http://www.opensource.org/licenses/bsd-license.php>. - * - * This software is distributed WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the License for more information. - */ - -#ifndef __CCD_COMPILER_H__ -#define __CCD_COMPILER_H__ - -#include <stddef.h> - -#define ccd_offsetof(TYPE, MEMBER) offsetof(TYPE, MEMBER) - -#define ccd_container_of(ptr, type, member) \ - (type *)( (char *)ptr - ccd_offsetof(type, member)) - - -/** - * Marks exported function. - */ -//#ifdef _WIN32 -//# ifdef libccd_EXPORTS -//# define _ccd_export __declspec(dllexport) -//# else /* libccd_EXPORTS */ -//# define _ccd_export __declspec(dllimport) -//# endif /* libccd_EXPORTS */ -//#else /* _WIN32 */ -//# define _ccd_export -//#endif /* _WIN32 */ - -#define _ccd_export - - -/** - * Marks inline function. - */ -#ifdef __GNUC__ -# define _ccd_inline static inline __attribute__((always_inline)) -#else /* __GNUC__ */ -# define _ccd_inline static __inline -#endif /* __GNUC__ */ - - -/** - * __prefetch(x) - prefetches the cacheline at "x" for read - * __prefetchw(x) - prefetches the cacheline at "x" for write - */ -#ifdef __GNUC__ -# define _ccd_prefetch(x) __builtin_prefetch(x) -# define _ccd_prefetchw(x) __builtin_prefetch(x,1) -#else /* __GNUC__ */ -# define _ccd_prefetch(x) ((void)0) -# define _ccd_prefetchw(x) ((void)0) -#endif /* __GNUC__ */ - - -#ifdef __ICC -// disable unused parameter warning -# pragma warning(disable:869) -// disable annoying "operands are evaluated in unspecified order" warning -# pragma warning(disable:981) -#endif /* __ICC */ - -#ifdef _MSC_VER -// disable unsafe function warning -# ifndef _CRT_SECURE_NO_WARNINGS -# define _CRT_SECURE_NO_WARNINGS -# endif -#endif /* _MSC_VER */ - -#endif /* __CCD_COMPILER_H__ */ - diff --git a/src/pe/extern/libccd/ccd/config.h.cmake.in b/src/pe/extern/libccd/ccd/config.h.cmake.in deleted file mode 100644 index 0515009164d1c01f11f1728cb4913338bbe808e8..0000000000000000000000000000000000000000 --- a/src/pe/extern/libccd/ccd/config.h.cmake.in +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __CCD_CONFIG_H__ -#define __CCD_CONFIG_H__ - -#cmakedefine CCD_SINGLE -#cmakedefine CCD_DOUBLE - -#endif /* __CCD_CONFIG_H__ */ diff --git a/src/pe/extern/libccd/ccd/config.h.m4 b/src/pe/extern/libccd/ccd/config.h.m4 deleted file mode 100644 index 4c11fbab0c11d9e9fd63ddd177fb262514732ee9..0000000000000000000000000000000000000000 --- a/src/pe/extern/libccd/ccd/config.h.m4 +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __CCD_CONFIG_H__ -#define __CCD_CONFIG_H__ - -ifdef(`USE_SINGLE', `#define CCD_SINGLE') -ifdef(`USE_DOUBLE', `#define CCD_DOUBLE') - -#endif /* __CCD_CONFIG_H__ */ diff --git a/src/pe/extern/libccd/ccd/quat.h b/src/pe/extern/libccd/ccd/quat.h deleted file mode 100644 index fc67532109560e904d7b90f02554c15b0f0a0ccf..0000000000000000000000000000000000000000 --- a/src/pe/extern/libccd/ccd/quat.h +++ /dev/null @@ -1,239 +0,0 @@ -/*** - * libccd - * --------------------------------- - * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> - * - * - * This file is part of libccd. - * - * Distributed under the OSI-approved BSD License (the "License"); - * see accompanying file BDS-LICENSE for details or see - * <http://www.opensource.org/licenses/bsd-license.php>. - * - * This software is distributed WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the License for more information. - */ - -#ifndef __CCD_QUAT_H__ -#define __CCD_QUAT_H__ - -#include <ccd/compiler.h> -#include <ccd/vec3.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -struct _ccd_quat_t { - ccd_real_t q[4]; //!< x, y, z, w -}; -typedef struct _ccd_quat_t ccd_quat_t; - -#define CCD_QUAT(name, x, y, z, w) \ - ccd_quat_t name = { {x, y, z, w} } - -_ccd_inline ccd_real_t ccdQuatLen2(const ccd_quat_t *q); -_ccd_inline ccd_real_t ccdQuatLen(const ccd_quat_t *q); - -_ccd_inline void ccdQuatSet(ccd_quat_t *q, ccd_real_t x, ccd_real_t y, ccd_real_t z, ccd_real_t w); -_ccd_inline void ccdQuatCopy(ccd_quat_t *dest, const ccd_quat_t *src); - -_ccd_inline int ccdQuatNormalize(ccd_quat_t *q); - -_ccd_inline void ccdQuatSetAngleAxis(ccd_quat_t *q, - ccd_real_t angle, const ccd_vec3_t *axis); - -_ccd_inline void ccdQuatScale(ccd_quat_t *q, ccd_real_t k); - -/** - * q = q * q2 - */ -_ccd_inline void ccdQuatMul(ccd_quat_t *q, const ccd_quat_t *q2); - -/** - * q = a * b - */ -_ccd_inline void ccdQuatMul2(ccd_quat_t *q, - const ccd_quat_t *a, const ccd_quat_t *b); - -/** - * Inverts quaternion. - * Returns 0 on success. - */ -_ccd_inline int ccdQuatInvert(ccd_quat_t *q); -_ccd_inline int ccdQuatInvert2(ccd_quat_t *dest, const ccd_quat_t *src); - - -/** - * Rotate vector v by quaternion q. - */ -_ccd_inline void ccdQuatRotVec(ccd_vec3_t *v, const ccd_quat_t *q); - - -/**** INLINES ****/ -_ccd_inline ccd_real_t ccdQuatLen2(const ccd_quat_t *q) -{ - ccd_real_t len; - - len = q->q[0] * q->q[0]; - len += q->q[1] * q->q[1]; - len += q->q[2] * q->q[2]; - len += q->q[3] * q->q[3]; - - return len; -} - -_ccd_inline ccd_real_t ccdQuatLen(const ccd_quat_t *q) -{ - return CCD_SQRT(ccdQuatLen2(q)); -} - -_ccd_inline void ccdQuatSet(ccd_quat_t *q, ccd_real_t x, ccd_real_t y, ccd_real_t z, ccd_real_t w) -{ - q->q[0] = x; - q->q[1] = y; - q->q[2] = z; - q->q[3] = w; -} - -_ccd_inline void ccdQuatCopy(ccd_quat_t *dest, const ccd_quat_t *src) -{ - *dest = *src; -} - - -_ccd_inline int ccdQuatNormalize(ccd_quat_t *q) -{ - ccd_real_t len = ccdQuatLen(q); - if (len < CCD_EPS) - return 0; - - ccdQuatScale(q, CCD_ONE / len); - return 1; -} - -_ccd_inline void ccdQuatSetAngleAxis(ccd_quat_t *q, - ccd_real_t angle, const ccd_vec3_t *axis) -{ - ccd_real_t a, x, y, z, n, s; - - a = angle/2; - x = ccdVec3X(axis); - y = ccdVec3Y(axis); - z = ccdVec3Z(axis); - n = CCD_SQRT(x*x + y*y + z*z); - - // axis==0? (treat this the same as angle==0 with an arbitrary axis) - if (n < CCD_EPS){ - q->q[0] = q->q[1] = q->q[2] = CCD_ZERO; - q->q[3] = CCD_ONE; - }else{ -#ifdef CCD_DOUBLE - s = sin(a)/n; -#else - s = sinf(a)/n; -#endif - -#ifdef CCD_DOUBLE - q->q[3] = cos(a); -#else - q->q[3] = cosf(a); -#endif - q->q[0] = x*s; - q->q[1] = y*s; - q->q[2] = z*s; - - ccdQuatNormalize(q); - } -} - - -_ccd_inline void ccdQuatScale(ccd_quat_t *q, ccd_real_t k) -{ - size_t i; - for (i = 0; i < 4; i++) - q->q[i] *= k; -} - -_ccd_inline void ccdQuatMul(ccd_quat_t *q, const ccd_quat_t *q2) -{ - ccd_quat_t a; - ccdQuatCopy(&a, q); - ccdQuatMul2(q, &a, q2); -} - -_ccd_inline void ccdQuatMul2(ccd_quat_t *q, - const ccd_quat_t *a, const ccd_quat_t *b) -{ - q->q[0] = a->q[3] * b->q[0] - + a->q[0] * b->q[3] - + a->q[1] * b->q[2] - - a->q[2] * b->q[1]; - q->q[1] = a->q[3] * b->q[1] - + a->q[1] * b->q[3] - - a->q[0] * b->q[2] - + a->q[2] * b->q[0]; - q->q[2] = a->q[3] * b->q[2] - + a->q[2] * b->q[3] - + a->q[0] * b->q[1] - - a->q[1] * b->q[0]; - q->q[3] = a->q[3] * b->q[3] - - a->q[0] * b->q[0] - - a->q[1] * b->q[1] - - a->q[2] * b->q[2]; -} - -_ccd_inline int ccdQuatInvert(ccd_quat_t *q) -{ - ccd_real_t len2 = ccdQuatLen2(q); - if (len2 < CCD_EPS) - return -1; - - len2 = CCD_ONE / len2; - - q->q[0] = -q->q[0] * len2; - q->q[1] = -q->q[1] * len2; - q->q[2] = -q->q[2] * len2; - q->q[3] = q->q[3] * len2; - - return 0; -} -_ccd_inline int ccdQuatInvert2(ccd_quat_t *dest, const ccd_quat_t *src) -{ - ccdQuatCopy(dest, src); - return ccdQuatInvert(dest); -} - -_ccd_inline void ccdQuatRotVec(ccd_vec3_t *v, const ccd_quat_t *q) -{ - // original version: 31 mul + 21 add - // optimized version: 18 mul + 12 add - // formula: v = v + 2 * cross(q.xyz, cross(q.xyz, v) + q.w * v) - ccd_real_t cross1_x, cross1_y, cross1_z, cross2_x, cross2_y, cross2_z; - ccd_real_t x, y, z, w; - ccd_real_t vx, vy, vz; - - vx = ccdVec3X(v); - vy = ccdVec3Y(v); - vz = ccdVec3Z(v); - - w = q->q[3]; - x = q->q[0]; - y = q->q[1]; - z = q->q[2]; - - cross1_x = y * vz - z * vy + w * vx; - cross1_y = z * vx - x * vz + w * vy; - cross1_z = x * vy - y * vx + w * vz; - cross2_x = y * cross1_z - z * cross1_y; - cross2_y = z * cross1_x - x * cross1_z; - cross2_z = x * cross1_y - y * cross1_x; - ccdVec3Set(v, vx + 2 * cross2_x, vy + 2 * cross2_y, vz + 2 * cross2_z); -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif /* __CCD_QUAT_H__ */ diff --git a/src/pe/extern/libccd/ccd/vec3.h b/src/pe/extern/libccd/ccd/vec3.h deleted file mode 100644 index b0c1b338f59cfc8e5c55903c1dae9d14463bb4dc..0000000000000000000000000000000000000000 --- a/src/pe/extern/libccd/ccd/vec3.h +++ /dev/null @@ -1,339 +0,0 @@ -/*** - * libccd - * --------------------------------- - * Copyright (c)2010-2013 Daniel Fiser <danfis@danfis.cz> - * - * - * This file is part of libccd. - * - * Distributed under the OSI-approved BSD License (the "License"); - * see accompanying file BDS-LICENSE for details or see - * <http://www.opensource.org/licenses/bsd-license.php>. - * - * This software is distributed WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the License for more information. - */ - -#ifndef __CCD_VEC3_H__ -#define __CCD_VEC3_H__ - -#include <math.h> -#include <float.h> -#include <stdlib.h> -#include <ccd/compiler.h> -#include <ccd/config.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#ifndef CCD_SINGLE -# ifndef CCD_DOUBLE -# error You must define CCD_SINGLE or CCD_DOUBLE -# endif /* CCD_DOUBLE */ -#endif /* CCD_SINGLE */ - -#ifdef WIN32 -# define CCD_FMIN(x, y) ((x) < (y) ? (x) : (y)) -#endif /* WIN32 */ - -#ifdef CCD_SINGLE -# ifdef CCD_DOUBLE -# error You can define either CCD_SINGLE or CCD_DOUBLE, not both! -# endif /* CCD_DOUBLE */ - -typedef float ccd_real_t; - -//# define CCD_EPS 1E-6 -# define CCD_EPS FLT_EPSILON - -# define CCD_REAL_MAX FLT_MAX - -# define CCD_REAL(x) (x ## f) /*!< form a constant */ -# define CCD_SQRT(x) (sqrtf(x)) /*!< square root */ -# define CCD_FABS(x) (fabsf(x)) /*!< absolute value */ -# define CCD_FMAX(x, y) (fmaxf((x), (y))) /*!< maximum of two floats */ - -# ifndef CCD_FMIN -# define CCD_FMIN(x, y) (fminf((x), (y))) /*!< minimum of two floats */ -# endif /* CCD_FMIN */ - -#endif /* CCD_SINGLE */ - -#ifdef CCD_DOUBLE -typedef double ccd_real_t; - -//# define CCD_EPS 1E-10 -# define CCD_EPS DBL_EPSILON - -# define CCD_REAL_MAX DBL_MAX - -# define CCD_REAL(x) (x) /*!< form a constant */ -# define CCD_SQRT(x) (sqrt(x)) /*!< square root */ -# define CCD_FABS(x) (fabs(x)) /*!< absolute value */ -# define CCD_FMAX(x, y) (fmax((x), (y))) /*!< maximum of two floats */ - -# ifndef CCD_FMIN -# define CCD_FMIN(x, y) (fmin((x), (y))) /*!< minimum of two floats */ -# endif /* CCD_FMIN */ - -#endif /* CCD_DOUBLE */ - -#define CCD_ONE CCD_REAL(1.) -#define CCD_ZERO CCD_REAL(0.) - -struct _ccd_vec3_t { - ccd_real_t v[3]; -}; -typedef struct _ccd_vec3_t ccd_vec3_t; - - -/** - * Holds origin (0,0,0) - this variable is meant to be read-only! - */ -extern ccd_vec3_t *ccd_vec3_origin; - -/** - * Array of points uniformly distributed on unit sphere. - */ -extern ccd_vec3_t *ccd_points_on_sphere; -extern size_t ccd_points_on_sphere_len; - -/** Returns sign of value. */ -_ccd_inline int ccdSign(ccd_real_t val); -/** Returns true if val is zero. **/ -_ccd_inline int ccdIsZero(ccd_real_t val); -/** Returns true if a and b equal. **/ -_ccd_inline int ccdEq(ccd_real_t a, ccd_real_t b); - - -#define CCD_VEC3_STATIC(x, y, z) \ - { { (x), (y), (z) } } - -#define CCD_VEC3(name, x, y, z) \ - ccd_vec3_t name = CCD_VEC3_STATIC((x), (y), (z)) - -_ccd_inline ccd_real_t ccdVec3X(const ccd_vec3_t *v); -_ccd_inline ccd_real_t ccdVec3Y(const ccd_vec3_t *v); -_ccd_inline ccd_real_t ccdVec3Z(const ccd_vec3_t *v); - -/** - * Returns true if a and b equal. - */ -_ccd_inline int ccdVec3Eq(const ccd_vec3_t *a, const ccd_vec3_t *b); - -/** - * Returns squared length of vector. - */ -_ccd_inline ccd_real_t ccdVec3Len2(const ccd_vec3_t *v); - -/** - * Returns distance between a and b. - */ -_ccd_inline ccd_real_t ccdVec3Dist2(const ccd_vec3_t *a, const ccd_vec3_t *b); - - -_ccd_inline void ccdVec3Set(ccd_vec3_t *v, ccd_real_t x, ccd_real_t y, ccd_real_t z); - -/** - * v = w - */ -_ccd_inline void ccdVec3Copy(ccd_vec3_t *v, const ccd_vec3_t *w); - -/** - * Substracts coordinates of vector w from vector v. v = v - w - */ -_ccd_inline void ccdVec3Sub(ccd_vec3_t *v, const ccd_vec3_t *w); - -/** - * Adds coordinates of vector w to vector v. v = v + w - */ -_ccd_inline void ccdVec3Add(ccd_vec3_t *v, const ccd_vec3_t *w); - -/** - * d = v - w - */ -_ccd_inline void ccdVec3Sub2(ccd_vec3_t *d, const ccd_vec3_t *v, const ccd_vec3_t *w); - -/** - * d = d * k; - */ -_ccd_inline void ccdVec3Scale(ccd_vec3_t *d, ccd_real_t k); - -/** - * Normalizes given vector to unit length. - */ -_ccd_inline void ccdVec3Normalize(ccd_vec3_t *d); - - -/** - * Dot product of two vectors. - */ -_ccd_inline ccd_real_t ccdVec3Dot(const ccd_vec3_t *a, const ccd_vec3_t *b); - -/** - * Cross product: d = a x b. - */ -_ccd_inline void ccdVec3Cross(ccd_vec3_t *d, const ccd_vec3_t *a, const ccd_vec3_t *b); - - -/** - * Returns distance^2 of point P to segment ab. - * If witness is non-NULL it is filled with coordinates of point from which - * was computed distance to point P. - */ -_ccd_export ccd_real_t ccdVec3PointSegmentDist2(const ccd_vec3_t *P, - const ccd_vec3_t *a, - const ccd_vec3_t *b, - ccd_vec3_t *witness); - -/** - * Returns distance^2 of point P from triangle formed by triplet a, b, c. - * If witness vector is provided it is filled with coordinates of point - * from which was computed distance to point P. - */ -_ccd_export ccd_real_t ccdVec3PointTriDist2(const ccd_vec3_t *P, - const ccd_vec3_t *a, - const ccd_vec3_t *b, - const ccd_vec3_t *c, - ccd_vec3_t *witness); - - -/**** INLINES ****/ -_ccd_inline int ccdSign(ccd_real_t val) -{ - if (ccdIsZero(val)){ - return 0; - }else if (val < CCD_ZERO){ - return -1; - } - return 1; -} - -_ccd_inline int ccdIsZero(ccd_real_t val) -{ - return CCD_FABS(val) < CCD_EPS; -} - -_ccd_inline int ccdEq(ccd_real_t _a, ccd_real_t _b) -{ - ccd_real_t ab; - ccd_real_t a, b; - - ab = CCD_FABS(_a - _b); - if (CCD_FABS(ab) < CCD_EPS) - return 1; - - a = CCD_FABS(_a); - b = CCD_FABS(_b); - if (b > a){ - return ab < CCD_EPS * b; - }else{ - return ab < CCD_EPS * a; - } -} - - -_ccd_inline ccd_real_t ccdVec3X(const ccd_vec3_t *v) -{ - return v->v[0]; -} - -_ccd_inline ccd_real_t ccdVec3Y(const ccd_vec3_t *v) -{ - return v->v[1]; -} - -_ccd_inline ccd_real_t ccdVec3Z(const ccd_vec3_t *v) -{ - return v->v[2]; -} - -_ccd_inline int ccdVec3Eq(const ccd_vec3_t *a, const ccd_vec3_t *b) -{ - return ccdEq(ccdVec3X(a), ccdVec3X(b)) - && ccdEq(ccdVec3Y(a), ccdVec3Y(b)) - && ccdEq(ccdVec3Z(a), ccdVec3Z(b)); -} - -_ccd_inline ccd_real_t ccdVec3Len2(const ccd_vec3_t *v) -{ - return ccdVec3Dot(v, v); -} - -_ccd_inline ccd_real_t ccdVec3Dist2(const ccd_vec3_t *a, const ccd_vec3_t *b) -{ - ccd_vec3_t ab; - ccdVec3Sub2(&ab, a, b); - return ccdVec3Len2(&ab); -} - -_ccd_inline void ccdVec3Set(ccd_vec3_t *v, ccd_real_t x, ccd_real_t y, ccd_real_t z) -{ - v->v[0] = x; - v->v[1] = y; - v->v[2] = z; -} - -_ccd_inline void ccdVec3Copy(ccd_vec3_t *v, const ccd_vec3_t *w) -{ - *v = *w; -} - -_ccd_inline void ccdVec3Sub(ccd_vec3_t *v, const ccd_vec3_t *w) -{ - v->v[0] -= w->v[0]; - v->v[1] -= w->v[1]; - v->v[2] -= w->v[2]; -} -_ccd_inline void ccdVec3Sub2(ccd_vec3_t *d, const ccd_vec3_t *v, const ccd_vec3_t *w) -{ - d->v[0] = v->v[0] - w->v[0]; - d->v[1] = v->v[1] - w->v[1]; - d->v[2] = v->v[2] - w->v[2]; -} - -_ccd_inline void ccdVec3Add(ccd_vec3_t *v, const ccd_vec3_t *w) -{ - v->v[0] += w->v[0]; - v->v[1] += w->v[1]; - v->v[2] += w->v[2]; -} - -_ccd_inline void ccdVec3Scale(ccd_vec3_t *d, ccd_real_t k) -{ - d->v[0] *= k; - d->v[1] *= k; - d->v[2] *= k; -} - -_ccd_inline void ccdVec3Normalize(ccd_vec3_t *d) -{ - ccd_real_t k = CCD_ONE / CCD_SQRT(ccdVec3Len2(d)); - ccdVec3Scale(d, k); -} - -_ccd_inline ccd_real_t ccdVec3Dot(const ccd_vec3_t *a, const ccd_vec3_t *b) -{ - ccd_real_t dot; - - dot = a->v[0] * b->v[0]; - dot += a->v[1] * b->v[1]; - dot += a->v[2] * b->v[2]; - return dot; -} - -_ccd_inline void ccdVec3Cross(ccd_vec3_t *d, const ccd_vec3_t *a, const ccd_vec3_t *b) -{ - d->v[0] = (a->v[1] * b->v[2]) - (a->v[2] * b->v[1]); - d->v[1] = (a->v[2] * b->v[0]) - (a->v[0] * b->v[2]); - d->v[2] = (a->v[0] * b->v[1]) - (a->v[1] * b->v[0]); -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif /* __CCD_VEC3_H__ */ diff --git a/src/pe/extern/libccd/dbg.h b/src/pe/extern/libccd/dbg.h deleted file mode 100644 index f4852c1a06a5b852fc80fadf3fa56e5dfd00a973..0000000000000000000000000000000000000000 --- a/src/pe/extern/libccd/dbg.h +++ /dev/null @@ -1,65 +0,0 @@ -/*** - * libccd - * --------------------------------- - * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> - * - * - * This file is part of libccd. - * - * Distributed under the OSI-approved BSD License (the "License"); - * see accompanying file BDS-LICENSE for details or see - * <http://www.opensource.org/licenses/bsd-license.php>. - * - * This software is distributed WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the License for more information. - */ - -#ifndef __CCD_DBG_H__ -#define __CCD_DBG_H__ - -/** - * Some macros which can be used for printing debug info to stderr if macro - * NDEBUG not defined. - * - * DBG_PROLOGUE can be specified as string and this string will be - * prepended to output text - */ -#ifndef NDEBUG - -#include <stdio.h> - -#ifndef DBG_PROLOGUE -# define DBG_PROLOGUE -#endif - -# define DBG(format, ...) do { \ - fprintf(stderr, DBG_PROLOGUE "%s :: " format "\n", __func__, ## __VA_ARGS__); \ - fflush(stderr); \ - } while (0) - -# define DBG2(str) do { \ - fprintf(stderr, DBG_PROLOGUE "%s :: " str "\n", __func__); \ - fflush(stderr); \ - } while (0) - -# define DBG_VEC3(vec, prefix) do {\ - fprintf(stderr, DBG_PROLOGUE "%s :: %s[%lf %lf %lf]\n", \ - __func__, prefix, ccdVec3X(vec), ccdVec3Y(vec), ccdVec3Z(vec)); \ - fflush(stderr); \ - } while (0) -/* -# define DBG_VEC3(vec, prefix) do {\ - fprintf(stderr, DBG_PROLOGUE "%s :: %s[%.20lf %.20lf %.20lf]\n", \ - __func__, prefix, ccdVec3X(vec), ccdVec3Y(vec), ccdVec3Z(vec)); \ - fflush(stderr); \ - } while (0) -*/ - -#else -# define DBG(format, ...) -# define DBG2(str) -# define DBG_VEC3(v, prefix) -#endif - -#endif /* __CCD_DBG_H__ */ diff --git a/src/pe/extern/libccd/list.h b/src/pe/extern/libccd/list.h deleted file mode 100644 index 40ea6328fa2633f430623662322ddd5cb65613a3..0000000000000000000000000000000000000000 --- a/src/pe/extern/libccd/list.h +++ /dev/null @@ -1,155 +0,0 @@ -/*** - * libccd - * --------------------------------- - * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> - * - * - * This file is part of libccd. - * - * Distributed under the OSI-approved BSD License (the "License"); - * see accompanying file BDS-LICENSE for details or see - * <http://www.opensource.org/licenses/bsd-license.php>. - * - * This software is distributed WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the License for more information. - */ - -#ifndef __CCD_LIST_H__ -#define __CCD_LIST_H__ - -#include <string.h> -#include <ccd/compiler.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -struct _ccd_list_t { - struct _ccd_list_t *next, *prev; -}; -typedef struct _ccd_list_t ccd_list_t; - - - -/** - * Get the struct for this entry. - * @ptr: the &ccd_list_t pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define ccdListEntry(ptr, type, member) \ - ccd_container_of(ptr, type, member) - -/** - * Iterates over list. - */ -#define ccdListForEach(list, item) \ - for (item = (list)->next; \ - _ccd_prefetch((item)->next), item != (list); \ - item = (item)->next) - -/** - * Iterates over list safe against remove of list entry - */ -#define ccdListForEachSafe(list, item, tmp) \ - for (item = (list)->next, tmp = (item)->next; \ - item != (list); \ - item = tmp, tmp = (item)->next) - -/** - * Iterates over list of given type. - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define ccdListForEachEntry(head, pos, postype, member) \ - for (pos = ccdListEntry((head)->next, postype, member); \ - _ccd_prefetch(pos->member.next), &pos->member != (head); \ - pos = ccdListEntry(pos->member.next, postype, member)) - -/** - * Iterates over list of given type safe against removal of list entry - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define ccdListForEachEntrySafe(head, pos, postype, n, ntype, member) \ - for (pos = ccdListEntry((head)->next, postype, member), \ - n = ccdListEntry(pos->member.next, postype, member); \ - &pos->member != (head); \ - pos = n, n = ccdListEntry(n->member.next, ntype, member)) - - -/** - * Initialize list. - */ -_ccd_inline void ccdListInit(ccd_list_t *l); - -_ccd_inline ccd_list_t *ccdListNext(ccd_list_t *l); -_ccd_inline ccd_list_t *ccdListPrev(ccd_list_t *l); - -/** - * Returns true if list is empty. - */ -_ccd_inline int ccdListEmpty(const ccd_list_t *head); - -/** - * Appends item to end of the list l. - */ -_ccd_inline void ccdListAppend(ccd_list_t *l, ccd_list_t *item); - -/** - * Removes item from list. - */ -_ccd_inline void ccdListDel(ccd_list_t *item); - - - -/// -/// INLINES: -/// - -_ccd_inline void ccdListInit(ccd_list_t *l) -{ - l->next = l; - l->prev = l; -} - -_ccd_inline ccd_list_t *ccdListNext(ccd_list_t *l) -{ - return l->next; -} - -_ccd_inline ccd_list_t *ccdListPrev(ccd_list_t *l) -{ - return l->prev; -} - -_ccd_inline int ccdListEmpty(const ccd_list_t *head) -{ - return head->next == head; -} - -_ccd_inline void ccdListAppend(ccd_list_t *l, ccd_list_t *new_element) -{ - new_element->prev = l->prev; - new_element->next = l; - l->prev->next = new_element; - l->prev = new_element; -} - -_ccd_inline void ccdListDel(ccd_list_t *item) -{ - item->next->prev = item->prev; - item->prev->next = item->next; - item->next = item; - item->prev = item; -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif /* __CCD_LIST_H__ */ diff --git a/src/pe/extern/libccd/mpr.c b/src/pe/extern/libccd/mpr.c deleted file mode 100644 index 5f5533a5bad9ba5a78be456f88e0ea0162af7b72..0000000000000000000000000000000000000000 --- a/src/pe/extern/libccd/mpr.c +++ /dev/null @@ -1,547 +0,0 @@ -/*** - * libccd - * --------------------------------- - * Copyright (c)2010,2011 Daniel Fiser <danfis@danfis.cz> - * - * - * This file is part of libccd. - * - * Distributed under the OSI-approved BSD License (the "License"); - * see accompanying file BDS-LICENSE for details or see - * <http://www.opensource.org/licenses/bsd-license.php>. - * - * This software is distributed WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the License for more information. - */ - -#include <stdlib.h> -#include <ccd/ccd.h> -#include "simplex.h" -#include "dbg.h" - -/** Finds origin (center) of Minkowski difference (actually it can be any - * interior point of Minkowski difference. */ -_ccd_inline void findOrigin(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_support_t *center); - -/** Discovers initial portal - that is tetrahedron that intersects with - * origin ray (ray from center of Minkowski diff to (0,0,0). - * - * Returns -1 if already recognized that origin is outside Minkowski - * portal. - * Returns 1 if origin lies on v1 of simplex (only v0 and v1 are present - * in simplex). - * Returns 2 if origin lies on v0-v1 segment. - * Returns 0 if portal was built. - */ -static int discoverPortal(const void *obj1, const void *obj2, - const ccd_t *ccd, ccd_simplex_t *portal); - - -/** Expands portal towards origin and determine if objects intersect. - * Already established portal must be given as argument. - * If intersection is found 0 is returned, -1 otherwise */ -static int refinePortal(const void *obj1, const void *obj2, - const ccd_t *ccd, ccd_simplex_t *portal); - -/** Finds penetration info by expanding provided portal. */ -static void findPenetr(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_simplex_t *portal, - ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos); - -/** Finds penetration info if origin lies on portal's v1 */ -static void findPenetrTouch(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_simplex_t *portal, - ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos); - -/** Find penetration info if origin lies on portal's segment v0-v1 */ -static void findPenetrSegment(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_simplex_t *portal, - ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos); - -/** Finds position vector from fully established portal */ -static void findPos(const void *obj1, const void *obj2, const ccd_t *ccd, - const ccd_simplex_t *portal, ccd_vec3_t *pos); - -/** Extends portal with new support point. - * Portal must have face v1-v2-v3 arranged to face outside portal. */ -_ccd_inline void expandPortal(ccd_simplex_t *portal, - const ccd_support_t *v4); - -/** Fill dir with direction outside portal. Portal's v1-v2-v3 face must be - * arranged in correct order! */ -_ccd_inline void portalDir(const ccd_simplex_t *portal, ccd_vec3_t *dir); - -/** Returns true if portal encapsules origin (0,0,0), dir is direction of - * v1-v2-v3 face. */ -_ccd_inline int portalEncapsulesOrigin(const ccd_simplex_t *portal, - const ccd_vec3_t *dir); - -/** Returns true if portal with new point v4 would reach specified - * tolerance (i.e. returns true if portal can _not_ significantly expand - * within Minkowski difference). - * - * v4 is candidate for new point in portal, dir is direction in which v4 - * was obtained. */ -_ccd_inline int portalReachTolerance(const ccd_simplex_t *portal, - const ccd_support_t *v4, - const ccd_vec3_t *dir, - const ccd_t *ccd); - -/** Returns true if portal expanded by new point v4 could possibly contain - * origin, dir is direction in which v4 was obtained. */ -_ccd_inline int portalCanEncapsuleOrigin(const ccd_simplex_t *portal, - const ccd_support_t *v4, - const ccd_vec3_t *dir); - - -int ccdMPRIntersect(const void *obj1, const void *obj2, const ccd_t *ccd) -{ - ccd_simplex_t portal; - int res; - - // Phase 1: Portal discovery - find portal that intersects with origin - // ray (ray from center of Minkowski diff to origin of coordinates) - res = discoverPortal(obj1, obj2, ccd, &portal); - if (res < 0) - return 0; - if (res > 0) - return 1; - - // Phase 2: Portal refinement - res = refinePortal(obj1, obj2, ccd, &portal); - return (res == 0 ? 1 : 0); -} - -int ccdMPRPenetration(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos) -{ - ccd_simplex_t portal; - int res; - - // Phase 1: Portal discovery - res = discoverPortal(obj1, obj2, ccd, &portal); - if (res < 0){ - // Origin isn't inside portal - no collision. - return -1; - - }else if (res == 1){ - // Touching contact on portal's v1. - findPenetrTouch(obj1, obj2, ccd, &portal, depth, dir, pos); - - }else if (res == 2){ - // Origin lies on v0-v1 segment. - findPenetrSegment(obj1, obj2, ccd, &portal, depth, dir, pos); - - }else if (res == 0){ - // Phase 2: Portal refinement - res = refinePortal(obj1, obj2, ccd, &portal); - if (res < 0) - return -1; - - // Phase 3. Penetration info - findPenetr(obj1, obj2, ccd, &portal, depth, dir, pos); - } - - return 0; -} - - - -_ccd_inline void findOrigin(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_support_t *center) -{ - ccd->center1(obj1, ¢er->v1); - ccd->center2(obj2, ¢er->v2); - ccdVec3Sub2(¢er->v, ¢er->v1, ¢er->v2); -} - -static int discoverPortal(const void *obj1, const void *obj2, - const ccd_t *ccd, ccd_simplex_t *portal) -{ - ccd_vec3_t dir, va, vb; - ccd_real_t dot; - int cont; - - // vertex 0 is center of portal - findOrigin(obj1, obj2, ccd, ccdSimplexPointW(portal, 0)); - ccdSimplexSetSize(portal, 1); - - if (ccdVec3Eq(&ccdSimplexPoint(portal, 0)->v, ccd_vec3_origin)){ - // Portal's center lies on origin (0,0,0) => we know that objects - // intersect but we would need to know penetration info. - // So move center little bit... - ccdVec3Set(&va, CCD_EPS * CCD_REAL(10.), CCD_ZERO, CCD_ZERO); - ccdVec3Add(&ccdSimplexPointW(portal, 0)->v, &va); - } - - - // vertex 1 = support in direction of origin - ccdVec3Copy(&dir, &ccdSimplexPoint(portal, 0)->v); - ccdVec3Scale(&dir, CCD_REAL(-1.)); - ccdVec3Normalize(&dir); - __ccdSupport(obj1, obj2, &dir, ccd, ccdSimplexPointW(portal, 1)); - ccdSimplexSetSize(portal, 2); - - // test if origin isn't outside of v1 - dot = ccdVec3Dot(&ccdSimplexPoint(portal, 1)->v, &dir); - if (ccdIsZero(dot) || dot < CCD_ZERO) - return -1; - - - // vertex 2 - ccdVec3Cross(&dir, &ccdSimplexPoint(portal, 0)->v, - &ccdSimplexPoint(portal, 1)->v); - if (ccdIsZero(ccdVec3Len2(&dir))){ - if (ccdVec3Eq(&ccdSimplexPoint(portal, 1)->v, ccd_vec3_origin)){ - // origin lies on v1 - return 1; - }else{ - // origin lies on v0-v1 segment - return 2; - } - } - - ccdVec3Normalize(&dir); - __ccdSupport(obj1, obj2, &dir, ccd, ccdSimplexPointW(portal, 2)); - dot = ccdVec3Dot(&ccdSimplexPoint(portal, 2)->v, &dir); - if (ccdIsZero(dot) || dot < CCD_ZERO) - return -1; - - ccdSimplexSetSize(portal, 3); - - // vertex 3 direction - ccdVec3Sub2(&va, &ccdSimplexPoint(portal, 1)->v, - &ccdSimplexPoint(portal, 0)->v); - ccdVec3Sub2(&vb, &ccdSimplexPoint(portal, 2)->v, - &ccdSimplexPoint(portal, 0)->v); - ccdVec3Cross(&dir, &va, &vb); - ccdVec3Normalize(&dir); - - // it is better to form portal faces to be oriented "outside" origin - dot = ccdVec3Dot(&dir, &ccdSimplexPoint(portal, 0)->v); - if (dot > CCD_ZERO){ - ccdSimplexSwap(portal, 1, 2); - ccdVec3Scale(&dir, CCD_REAL(-1.)); - } - - while (ccdSimplexSize(portal) < 4){ - __ccdSupport(obj1, obj2, &dir, ccd, ccdSimplexPointW(portal, 3)); - dot = ccdVec3Dot(&ccdSimplexPoint(portal, 3)->v, &dir); - if (ccdIsZero(dot) || dot < CCD_ZERO) - return -1; - - cont = 0; - - // test if origin is outside (v1, v0, v3) - set v2 as v3 and - // continue - ccdVec3Cross(&va, &ccdSimplexPoint(portal, 1)->v, - &ccdSimplexPoint(portal, 3)->v); - dot = ccdVec3Dot(&va, &ccdSimplexPoint(portal, 0)->v); - if (dot < CCD_ZERO && !ccdIsZero(dot)){ - ccdSimplexSet(portal, 2, ccdSimplexPoint(portal, 3)); - cont = 1; - } - - if (!cont){ - // test if origin is outside (v3, v0, v2) - set v1 as v3 and - // continue - ccdVec3Cross(&va, &ccdSimplexPoint(portal, 3)->v, - &ccdSimplexPoint(portal, 2)->v); - dot = ccdVec3Dot(&va, &ccdSimplexPoint(portal, 0)->v); - if (dot < CCD_ZERO && !ccdIsZero(dot)){ - ccdSimplexSet(portal, 1, ccdSimplexPoint(portal, 3)); - cont = 1; - } - } - - if (cont){ - ccdVec3Sub2(&va, &ccdSimplexPoint(portal, 1)->v, - &ccdSimplexPoint(portal, 0)->v); - ccdVec3Sub2(&vb, &ccdSimplexPoint(portal, 2)->v, - &ccdSimplexPoint(portal, 0)->v); - ccdVec3Cross(&dir, &va, &vb); - ccdVec3Normalize(&dir); - }else{ - ccdSimplexSetSize(portal, 4); - } - } - - return 0; -} - -static int refinePortal(const void *obj1, const void *obj2, - const ccd_t *ccd, ccd_simplex_t *portal) -{ - ccd_vec3_t dir; - ccd_support_t v4; - - while (1){ - // compute direction outside the portal (from v0 throught v1,v2,v3 - // face) - portalDir(portal, &dir); - - // test if origin is inside the portal - if (portalEncapsulesOrigin(portal, &dir)) - return 0; - - // get next support point - __ccdSupport(obj1, obj2, &dir, ccd, &v4); - - // test if v4 can expand portal to contain origin and if portal - // expanding doesn't reach given tolerance - if (!portalCanEncapsuleOrigin(portal, &v4, &dir) - || portalReachTolerance(portal, &v4, &dir, ccd)){ - return -1; - } - - // v1-v2-v3 triangle must be rearranged to face outside Minkowski - // difference (direction from v0). - expandPortal(portal, &v4); - } - - return -1; -} - - -static void findPenetr(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_simplex_t *portal, - ccd_real_t *depth, ccd_vec3_t *pdir, ccd_vec3_t *pos) -{ - ccd_vec3_t dir; - ccd_support_t v4; - unsigned long iterations; - - iterations = 0UL; - while (1){ - // compute portal direction and obtain next support point - portalDir(portal, &dir); - __ccdSupport(obj1, obj2, &dir, ccd, &v4); - - // reached tolerance -> find penetration info - if (portalReachTolerance(portal, &v4, &dir, ccd) - || iterations > ccd->max_iterations){ - *depth = ccdVec3PointTriDist2(ccd_vec3_origin, - &ccdSimplexPoint(portal, 1)->v, - &ccdSimplexPoint(portal, 2)->v, - &ccdSimplexPoint(portal, 3)->v, - pdir); - *depth = CCD_SQRT(*depth); - ccdVec3Normalize(pdir); - - // barycentric coordinates: - findPos(obj1, obj2, ccd, portal, pos); - - return; - } - - expandPortal(portal, &v4); - - iterations++; - } -} - -static void findPenetrTouch(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_simplex_t *portal, - ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos) -{ - (void)(obj1); - (void)(obj2); - (void)(ccd); - // Touching contact on portal's v1 - so depth is zero and direction - // is unimportant and pos can be guessed - *depth = CCD_REAL(0.); - ccdVec3Copy(dir, ccd_vec3_origin); - - ccdVec3Copy(pos, &ccdSimplexPoint(portal, 1)->v1); - ccdVec3Add(pos, &ccdSimplexPoint(portal, 1)->v2); - ccdVec3Scale(pos, 0.5); -} - -static void findPenetrSegment(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_simplex_t *portal, - ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos) -{ - (void)(obj1); - (void)(obj2); - (void)(ccd); - - /* - ccd_vec3_t vec; - ccd_real_t k; - */ - - // Origin lies on v0-v1 segment. - // Depth is distance to v1, direction also and position must be - // computed - - ccdVec3Copy(pos, &ccdSimplexPoint(portal, 1)->v1); - ccdVec3Add(pos, &ccdSimplexPoint(portal, 1)->v2); - ccdVec3Scale(pos, CCD_REAL(0.5)); - - /* - ccdVec3Sub2(&vec, &ccdSimplexPoint(portal, 1)->v, - &ccdSimplexPoint(portal, 0)->v); - k = CCD_SQRT(ccdVec3Len2(&ccdSimplexPoint(portal, 0)->v)); - k /= CCD_SQRT(ccdVec3Len2(&vec)); - ccdVec3Scale(&vec, -k); - ccdVec3Add(pos, &vec); - */ - - ccdVec3Copy(dir, &ccdSimplexPoint(portal, 1)->v); - *depth = CCD_SQRT(ccdVec3Len2(dir)); - ccdVec3Normalize(dir); -} - - -static void findPos(const void *obj1, const void *obj2, const ccd_t *ccd, - const ccd_simplex_t *portal, ccd_vec3_t *pos) -{ - (void)(obj1); - (void)(obj2); - (void)(ccd); - - ccd_vec3_t dir; - size_t i; - ccd_real_t b[4], sum, inv; - ccd_vec3_t vec, p1, p2; - - portalDir(portal, &dir); - - // use barycentric coordinates of tetrahedron to find origin - ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 1)->v, - &ccdSimplexPoint(portal, 2)->v); - b[0] = ccdVec3Dot(&vec, &ccdSimplexPoint(portal, 3)->v); - - ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 3)->v, - &ccdSimplexPoint(portal, 2)->v); - b[1] = ccdVec3Dot(&vec, &ccdSimplexPoint(portal, 0)->v); - - ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 0)->v, - &ccdSimplexPoint(portal, 1)->v); - b[2] = ccdVec3Dot(&vec, &ccdSimplexPoint(portal, 3)->v); - - ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 2)->v, - &ccdSimplexPoint(portal, 1)->v); - b[3] = ccdVec3Dot(&vec, &ccdSimplexPoint(portal, 0)->v); - - sum = b[0] + b[1] + b[2] + b[3]; - - if (ccdIsZero(sum) || sum < CCD_ZERO){ - b[0] = CCD_REAL(0.); - - ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 2)->v, - &ccdSimplexPoint(portal, 3)->v); - b[1] = ccdVec3Dot(&vec, &dir); - ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 3)->v, - &ccdSimplexPoint(portal, 1)->v); - b[2] = ccdVec3Dot(&vec, &dir); - ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 1)->v, - &ccdSimplexPoint(portal, 2)->v); - b[3] = ccdVec3Dot(&vec, &dir); - - sum = b[1] + b[2] + b[3]; - } - - inv = CCD_REAL(1.) / sum; - - ccdVec3Copy(&p1, ccd_vec3_origin); - ccdVec3Copy(&p2, ccd_vec3_origin); - for (i = 0; i < 4; i++){ - ccdVec3Copy(&vec, &ccdSimplexPoint(portal, (int)i)->v1); - ccdVec3Scale(&vec, b[i]); - ccdVec3Add(&p1, &vec); - - ccdVec3Copy(&vec, &ccdSimplexPoint(portal, (int)i)->v2); - ccdVec3Scale(&vec, b[i]); - ccdVec3Add(&p2, &vec); - } - ccdVec3Scale(&p1, inv); - ccdVec3Scale(&p2, inv); - - ccdVec3Copy(pos, &p1); - ccdVec3Add(pos, &p2); - ccdVec3Scale(pos, 0.5); -} - -_ccd_inline void expandPortal(ccd_simplex_t *portal, - const ccd_support_t *v4) -{ - ccd_real_t dot; - ccd_vec3_t v4v0; - - ccdVec3Cross(&v4v0, &v4->v, &ccdSimplexPoint(portal, 0)->v); - dot = ccdVec3Dot(&ccdSimplexPoint(portal, 1)->v, &v4v0); - if (dot > CCD_ZERO){ - dot = ccdVec3Dot(&ccdSimplexPoint(portal, 2)->v, &v4v0); - if (dot > CCD_ZERO){ - ccdSimplexSet(portal, 1, v4); - }else{ - ccdSimplexSet(portal, 3, v4); - } - }else{ - dot = ccdVec3Dot(&ccdSimplexPoint(portal, 3)->v, &v4v0); - if (dot > CCD_ZERO){ - ccdSimplexSet(portal, 2, v4); - }else{ - ccdSimplexSet(portal, 1, v4); - } - } -} - -_ccd_inline void portalDir(const ccd_simplex_t *portal, ccd_vec3_t *dir) -{ - ccd_vec3_t v2v1, v3v1; - - ccdVec3Sub2(&v2v1, &ccdSimplexPoint(portal, 2)->v, - &ccdSimplexPoint(portal, 1)->v); - ccdVec3Sub2(&v3v1, &ccdSimplexPoint(portal, 3)->v, - &ccdSimplexPoint(portal, 1)->v); - ccdVec3Cross(dir, &v2v1, &v3v1); - ccdVec3Normalize(dir); -} - -_ccd_inline int portalEncapsulesOrigin(const ccd_simplex_t *portal, - const ccd_vec3_t *dir) -{ - ccd_real_t dot; - dot = ccdVec3Dot(dir, &ccdSimplexPoint(portal, 1)->v); - return ccdIsZero(dot) || dot > CCD_ZERO; -} - -_ccd_inline int portalReachTolerance(const ccd_simplex_t *portal, - const ccd_support_t *v4, - const ccd_vec3_t *dir, - const ccd_t *ccd) -{ - ccd_real_t dv1, dv2, dv3, dv4; - ccd_real_t dot1, dot2, dot3; - - // find the smallest dot product of dir and {v1-v4, v2-v4, v3-v4} - - dv1 = ccdVec3Dot(&ccdSimplexPoint(portal, 1)->v, dir); - dv2 = ccdVec3Dot(&ccdSimplexPoint(portal, 2)->v, dir); - dv3 = ccdVec3Dot(&ccdSimplexPoint(portal, 3)->v, dir); - dv4 = ccdVec3Dot(&v4->v, dir); - - dot1 = dv4 - dv1; - dot2 = dv4 - dv2; - dot3 = dv4 - dv3; - - dot1 = CCD_FMIN(dot1, dot2); - dot1 = CCD_FMIN(dot1, dot3); - - return ccdEq(dot1, ccd->mpr_tolerance) || dot1 < ccd->mpr_tolerance; -} - -_ccd_inline int portalCanEncapsuleOrigin(const ccd_simplex_t *portal, - const ccd_support_t *v4, - const ccd_vec3_t *dir) -{ - (void)(portal); - - ccd_real_t dot; - dot = ccdVec3Dot(&v4->v, dir); - return ccdIsZero(dot) || dot > CCD_ZERO; -} diff --git a/src/pe/extern/libccd/polytope.c b/src/pe/extern/libccd/polytope.c deleted file mode 100644 index 527016cdee360a5eba62e8063720b63c3b010a81..0000000000000000000000000000000000000000 --- a/src/pe/extern/libccd/polytope.c +++ /dev/null @@ -1,298 +0,0 @@ -/*** - * libccd - * --------------------------------- - * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> - * - * - * This file is part of libccd. - * - * Distributed under the OSI-approved BSD License (the "License"); - * see accompanying file BDS-LICENSE for details or see - * <http://www.opensource.org/licenses/bsd-license.php>. - * - * This software is distributed WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the License for more information. - */ - -#include <stdio.h> -#include <float.h> -#include "polytope.h" -#include "alloc.h" - -_ccd_inline void _ccdPtNearestUpdate(ccd_pt_t *pt, ccd_pt_el_t *el) -{ - if (ccdEq(pt->nearest_dist, el->dist)){ - if (el->type < pt->nearest_type){ - pt->nearest = el; - pt->nearest_dist = el->dist; - pt->nearest_type = el->type; - } - }else if (el->dist < pt->nearest_dist){ - pt->nearest = el; - pt->nearest_dist = el->dist; - pt->nearest_type = el->type; - } -} - -static void _ccdPtNearestRenew(ccd_pt_t *pt) -{ - ccd_pt_vertex_t *v; - ccd_pt_edge_t *e; - ccd_pt_face_t *f; - - pt->nearest_dist = CCD_REAL_MAX; - pt->nearest_type = 3; - pt->nearest = NULL; - - ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){ - _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)v); - } - - ccdListForEachEntry(&pt->edges, e, ccd_pt_edge_t, list){ - _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)e); - } - - ccdListForEachEntry(&pt->faces, f, ccd_pt_face_t, list){ - _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)f); - } -} - - - -void ccdPtInit(ccd_pt_t *pt) -{ - ccdListInit(&pt->vertices); - ccdListInit(&pt->edges); - ccdListInit(&pt->faces); - - pt->nearest = NULL; - pt->nearest_dist = CCD_REAL_MAX; - pt->nearest_type = 3; -} - -void ccdPtDestroy(ccd_pt_t *pt) -{ - ccd_pt_face_t *f, *f2; - ccd_pt_edge_t *e, *e2; - ccd_pt_vertex_t *v, *v2; - - // first delete all faces - ccdListForEachEntrySafe(&pt->faces, f, ccd_pt_face_t, f2, ccd_pt_face_t, list){ - ccdPtDelFace(pt, f); - } - - // delete all edges - ccdListForEachEntrySafe(&pt->edges, e, ccd_pt_edge_t, e2, ccd_pt_edge_t, list){ - ccdPtDelEdge(pt, e); - } - - // delete all vertices - ccdListForEachEntrySafe(&pt->vertices, v, ccd_pt_vertex_t, v2, ccd_pt_vertex_t, list){ - ccdPtDelVertex(pt, v); - } -} - - -ccd_pt_vertex_t *ccdPtAddVertex(ccd_pt_t *pt, const ccd_support_t *v) -{ - ccd_pt_vertex_t *vert; - - vert = CCD_ALLOC(ccd_pt_vertex_t); - if (vert == NULL) - return NULL; - - vert->type = CCD_PT_VERTEX; - ccdSupportCopy(&vert->v, v); - - vert->dist = ccdVec3Len2(&vert->v.v); - ccdVec3Copy(&vert->witness, &vert->v.v); - - ccdListInit(&vert->edges); - - // add vertex to list - ccdListAppend(&pt->vertices, &vert->list); - - // update position in .nearest array - _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)vert); - - return vert; -} - -ccd_pt_edge_t *ccdPtAddEdge(ccd_pt_t *pt, ccd_pt_vertex_t *v1, - ccd_pt_vertex_t *v2) -{ - const ccd_vec3_t *a, *b; - ccd_pt_edge_t *edge; - - if (v1 == NULL || v2 == NULL) - return NULL; - - edge = CCD_ALLOC(ccd_pt_edge_t); - if (edge == NULL) - return NULL; - - edge->type = CCD_PT_EDGE; - edge->vertex[0] = v1; - edge->vertex[1] = v2; - edge->faces[0] = edge->faces[1] = NULL; - - a = &edge->vertex[0]->v.v; - b = &edge->vertex[1]->v.v; - edge->dist = ccdVec3PointSegmentDist2(ccd_vec3_origin, a, b, &edge->witness); - - ccdListAppend(&edge->vertex[0]->edges, &edge->vertex_list[0]); - ccdListAppend(&edge->vertex[1]->edges, &edge->vertex_list[1]); - - ccdListAppend(&pt->edges, &edge->list); - - // update position in .nearest array - _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)edge); - - return edge; -} - -ccd_pt_face_t *ccdPtAddFace(ccd_pt_t *pt, ccd_pt_edge_t *e1, - ccd_pt_edge_t *e2, - ccd_pt_edge_t *e3) -{ - const ccd_vec3_t *a, *b, *c; - ccd_pt_face_t *face; - ccd_pt_edge_t *e; - size_t i; - - if (e1 == NULL || e2 == NULL || e3 == NULL) - return NULL; - - face = CCD_ALLOC(ccd_pt_face_t); - if (face == NULL) - return NULL; - - face->type = CCD_PT_FACE; - face->edge[0] = e1; - face->edge[1] = e2; - face->edge[2] = e3; - - // obtain triplet of vertices - a = &face->edge[0]->vertex[0]->v.v; - b = &face->edge[0]->vertex[1]->v.v; - e = face->edge[1]; - if (e->vertex[0] != face->edge[0]->vertex[0] - && e->vertex[0] != face->edge[0]->vertex[1]){ - c = &e->vertex[0]->v.v; - }else{ - c = &e->vertex[1]->v.v; - } - face->dist = ccdVec3PointTriDist2(ccd_vec3_origin, a, b, c, &face->witness); - - - for (i = 0; i < 3; i++){ - if (face->edge[i]->faces[0] == NULL){ - face->edge[i]->faces[0] = face; - }else{ - face->edge[i]->faces[1] = face; - } - } - - ccdListAppend(&pt->faces, &face->list); - - // update position in .nearest array - _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)face); - - return face; -} - - -void ccdPtRecomputeDistances(ccd_pt_t *pt) -{ - ccd_pt_vertex_t *v; - ccd_pt_edge_t *e; - ccd_pt_face_t *f; - const ccd_vec3_t *a, *b, *c; - ccd_real_t dist; - - ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){ - dist = ccdVec3Len2(&v->v.v); - v->dist = dist; - ccdVec3Copy(&v->witness, &v->v.v); - } - - ccdListForEachEntry(&pt->edges, e, ccd_pt_edge_t, list){ - a = &e->vertex[0]->v.v; - b = &e->vertex[1]->v.v; - dist = ccdVec3PointSegmentDist2(ccd_vec3_origin, a, b, &e->witness); - e->dist = dist; - } - - ccdListForEachEntry(&pt->faces, f, ccd_pt_face_t, list){ - // obtain triplet of vertices - a = &f->edge[0]->vertex[0]->v.v; - b = &f->edge[0]->vertex[1]->v.v; - e = f->edge[1]; - if (e->vertex[0] != f->edge[0]->vertex[0] - && e->vertex[0] != f->edge[0]->vertex[1]){ - c = &e->vertex[0]->v.v; - }else{ - c = &e->vertex[1]->v.v; - } - - dist = ccdVec3PointTriDist2(ccd_vec3_origin, a, b, c, &f->witness); - f->dist = dist; - } -} - -ccd_pt_el_t *ccdPtNearest(ccd_pt_t *pt) -{ - if (!pt->nearest){ - _ccdPtNearestRenew(pt); - } - return pt->nearest; -} - - -void ccdPtDumpSVT(ccd_pt_t *pt, const char *fn) -{ - FILE *fout; - - fout = fopen(fn, "a"); - if (fout == NULL) - return; - - ccdPtDumpSVT2(pt, fout); - - fclose(fout); -} - -void ccdPtDumpSVT2(ccd_pt_t *pt, FILE *fout) -{ - ccd_pt_vertex_t *v, *a, *b, *c; - ccd_pt_edge_t *e; - ccd_pt_face_t *f; - size_t i; - - fprintf(fout, "-----\n"); - - fprintf(fout, "Points:\n"); - i = 0; - ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){ - v->id = (int)(i++); - fprintf(fout, "%lf %lf %lf\n", - ccdVec3X(&v->v.v), ccdVec3Y(&v->v.v), ccdVec3Z(&v->v.v)); - } - - fprintf(fout, "Edges:\n"); - ccdListForEachEntry(&pt->edges, e, ccd_pt_edge_t, list){ - fprintf(fout, "%d %d\n", e->vertex[0]->id, e->vertex[1]->id); - } - - fprintf(fout, "Faces:\n"); - ccdListForEachEntry(&pt->faces, f, ccd_pt_face_t, list){ - a = f->edge[0]->vertex[0]; - b = f->edge[0]->vertex[1]; - c = f->edge[1]->vertex[0]; - if (c == a || c == b){ - c = f->edge[1]->vertex[1]; - } - fprintf(fout, "%d %d %d\n", a->id, b->id, c->id); - } -} diff --git a/src/pe/extern/libccd/polytope.h b/src/pe/extern/libccd/polytope.h deleted file mode 100644 index b671224ebf904208fe7b9b3aee7267fcf7aec696..0000000000000000000000000000000000000000 --- a/src/pe/extern/libccd/polytope.h +++ /dev/null @@ -1,322 +0,0 @@ -/*** - * libccd - * --------------------------------- - * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> - * - * - * This file is part of libccd. - * - * Distributed under the OSI-approved BSD License (the "License"); - * see accompanying file BDS-LICENSE for details or see - * <http://www.opensource.org/licenses/bsd-license.php>. - * - * This software is distributed WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the License for more information. - */ - -#ifndef __CCD_POLYTOPE_H__ -#define __CCD_POLYTOPE_H__ - -#include <stdlib.h> -#include <stdio.h> -#include "support.h" -#include "list.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define CCD_PT_VERTEX 1 -#define CCD_PT_EDGE 2 -#define CCD_PT_FACE 3 - - -#define __CCD_PT_EL \ - int type; /*! type of element */ \ - ccd_real_t dist; /*! distance from origin */ \ - ccd_vec3_t witness; /*! witness point of projection of origin */ \ - ccd_list_t list; /*! list of elements of same type */ - -/** - * General polytope element. - * Could be vertex, edge or triangle. - */ -struct _ccd_pt_el_t { - __CCD_PT_EL -}; -typedef struct _ccd_pt_el_t ccd_pt_el_t; - -struct _ccd_pt_edge_t; -struct _ccd_pt_face_t; - -/** - * Polytope's vertex. - */ -struct _ccd_pt_vertex_t { - __CCD_PT_EL - - int id; - ccd_support_t v; - ccd_list_t edges; //!< List of edges -}; -typedef struct _ccd_pt_vertex_t ccd_pt_vertex_t; - -/** - * Polytope's edge. - */ -struct _ccd_pt_edge_t { - __CCD_PT_EL - - ccd_pt_vertex_t *vertex[2]; //!< Reference to vertices - struct _ccd_pt_face_t *faces[2]; //!< Reference to faces - - ccd_list_t vertex_list[2]; //!< List items in vertices' lists -}; -typedef struct _ccd_pt_edge_t ccd_pt_edge_t; - -/** - * Polytope's triangle faces. - */ -struct _ccd_pt_face_t { - __CCD_PT_EL - - ccd_pt_edge_t *edge[3]; //!< Reference to surrounding edges -}; -typedef struct _ccd_pt_face_t ccd_pt_face_t; - - -/** - * Struct containing polytope. - */ -struct _ccd_pt_t { - ccd_list_t vertices; //!< List of vertices - ccd_list_t edges; //!< List of edges - ccd_list_t faces; //!< List of faces - - ccd_pt_el_t *nearest; - ccd_real_t nearest_dist; - int nearest_type; -}; -typedef struct _ccd_pt_t ccd_pt_t; - - -void ccdPtInit(ccd_pt_t *pt); -void ccdPtDestroy(ccd_pt_t *pt); - -/** - * Returns vertices surrounding given triangle face. - */ -_ccd_inline void ccdPtFaceVec3(const ccd_pt_face_t *face, - ccd_vec3_t **a, - ccd_vec3_t **b, - ccd_vec3_t **c); -_ccd_inline void ccdPtFaceVertices(const ccd_pt_face_t *face, - ccd_pt_vertex_t **a, - ccd_pt_vertex_t **b, - ccd_pt_vertex_t **c); -_ccd_inline void ccdPtFaceEdges(const ccd_pt_face_t *f, - ccd_pt_edge_t **a, - ccd_pt_edge_t **b, - ccd_pt_edge_t **c); - -_ccd_inline void ccdPtEdgeVec3(const ccd_pt_edge_t *e, - ccd_vec3_t **a, - ccd_vec3_t **b); -_ccd_inline void ccdPtEdgeVertices(const ccd_pt_edge_t *e, - ccd_pt_vertex_t **a, - ccd_pt_vertex_t **b); -_ccd_inline void ccdPtEdgeFaces(const ccd_pt_edge_t *e, - ccd_pt_face_t **f1, - ccd_pt_face_t **f2); - - -/** - * Adds vertex to polytope and returns pointer to newly created vertex. - */ -ccd_pt_vertex_t *ccdPtAddVertex(ccd_pt_t *pt, const ccd_support_t *v); -_ccd_inline ccd_pt_vertex_t *ccdPtAddVertexCoords(ccd_pt_t *pt, - ccd_real_t x, ccd_real_t y, ccd_real_t z); - -/** - * Adds edge to polytope. - */ -ccd_pt_edge_t *ccdPtAddEdge(ccd_pt_t *pt, ccd_pt_vertex_t *v1, - ccd_pt_vertex_t *v2); - -/** - * Adds face to polytope. - */ -ccd_pt_face_t *ccdPtAddFace(ccd_pt_t *pt, ccd_pt_edge_t *e1, - ccd_pt_edge_t *e2, - ccd_pt_edge_t *e3); - -/** - * Deletes vertex from polytope. - * Returns 0 on success, -1 otherwise. - */ -_ccd_inline int ccdPtDelVertex(ccd_pt_t *pt, ccd_pt_vertex_t *); -_ccd_inline int ccdPtDelEdge(ccd_pt_t *pt, ccd_pt_edge_t *); -_ccd_inline int ccdPtDelFace(ccd_pt_t *pt, ccd_pt_face_t *); - - -/** - * Recompute distances from origin for all elements in pt. - */ -void ccdPtRecomputeDistances(ccd_pt_t *pt); - -/** - * Returns nearest element to origin. - */ -ccd_pt_el_t *ccdPtNearest(ccd_pt_t *pt); - - -void ccdPtDumpSVT(ccd_pt_t *pt, const char *fn); -void ccdPtDumpSVT2(ccd_pt_t *pt, FILE *); - - -/**** INLINES ****/ -_ccd_inline ccd_pt_vertex_t *ccdPtAddVertexCoords(ccd_pt_t *pt, - ccd_real_t x, ccd_real_t y, ccd_real_t z) -{ - ccd_support_t s; - ccdVec3Set(&s.v, x, y, z); - return ccdPtAddVertex(pt, &s); -} - -_ccd_inline int ccdPtDelVertex(ccd_pt_t *pt, ccd_pt_vertex_t *v) -{ - // test if any edge is connected to this vertex - if (!ccdListEmpty(&v->edges)) - return -1; - - // delete vertex from main list - ccdListDel(&v->list); - - if ((void *)pt->nearest == (void *)v){ - pt->nearest = NULL; - } - - free(v); - return 0; -} - -_ccd_inline int ccdPtDelEdge(ccd_pt_t *pt, ccd_pt_edge_t *e) -{ - // text if any face is connected to this edge (faces[] is always - // aligned to lower indices) - if (e->faces[0] != NULL) - return -1; - - // disconnect edge from lists of edges in vertex struct - ccdListDel(&e->vertex_list[0]); - ccdListDel(&e->vertex_list[1]); - - // disconnect edge from main list - ccdListDel(&e->list); - - if ((void *)pt->nearest == (void *)e){ - pt->nearest = NULL; - } - - free(e); - return 0; -} - -_ccd_inline int ccdPtDelFace(ccd_pt_t *pt, ccd_pt_face_t *f) -{ - ccd_pt_edge_t *e; - size_t i; - - // remove face from edges' recerence lists - for (i = 0; i < 3; i++){ - e = f->edge[i]; - if (e->faces[0] == f){ - e->faces[0] = e->faces[1]; - } - e->faces[1] = NULL; - } - - // remove face from list of all faces - ccdListDel(&f->list); - - if ((void *)pt->nearest == (void *)f){ - pt->nearest = NULL; - } - - free(f); - return 0; -} - -_ccd_inline void ccdPtFaceVec3(const ccd_pt_face_t *face, - ccd_vec3_t **a, - ccd_vec3_t **b, - ccd_vec3_t **c) -{ - *a = &face->edge[0]->vertex[0]->v.v; - *b = &face->edge[0]->vertex[1]->v.v; - - if (face->edge[1]->vertex[0] != face->edge[0]->vertex[0] - && face->edge[1]->vertex[0] != face->edge[0]->vertex[1]){ - *c = &face->edge[1]->vertex[0]->v.v; - }else{ - *c = &face->edge[1]->vertex[1]->v.v; - } -} - -_ccd_inline void ccdPtFaceVertices(const ccd_pt_face_t *face, - ccd_pt_vertex_t **a, - ccd_pt_vertex_t **b, - ccd_pt_vertex_t **c) -{ - *a = face->edge[0]->vertex[0]; - *b = face->edge[0]->vertex[1]; - - if (face->edge[1]->vertex[0] != face->edge[0]->vertex[0] - && face->edge[1]->vertex[0] != face->edge[0]->vertex[1]){ - *c = face->edge[1]->vertex[0]; - }else{ - *c = face->edge[1]->vertex[1]; - } -} - -_ccd_inline void ccdPtFaceEdges(const ccd_pt_face_t *f, - ccd_pt_edge_t **a, - ccd_pt_edge_t **b, - ccd_pt_edge_t **c) -{ - *a = f->edge[0]; - *b = f->edge[1]; - *c = f->edge[2]; -} - -_ccd_inline void ccdPtEdgeVec3(const ccd_pt_edge_t *e, - ccd_vec3_t **a, - ccd_vec3_t **b) -{ - *a = &e->vertex[0]->v.v; - *b = &e->vertex[1]->v.v; -} - -_ccd_inline void ccdPtEdgeVertices(const ccd_pt_edge_t *e, - ccd_pt_vertex_t **a, - ccd_pt_vertex_t **b) -{ - *a = e->vertex[0]; - *b = e->vertex[1]; -} - -_ccd_inline void ccdPtEdgeFaces(const ccd_pt_edge_t *e, - ccd_pt_face_t **f1, - ccd_pt_face_t **f2) -{ - *f1 = e->faces[0]; - *f2 = e->faces[1]; -} - - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif /* __CCD_POLYTOPE_H__ */ diff --git a/src/pe/extern/libccd/simplex.h b/src/pe/extern/libccd/simplex.h deleted file mode 100644 index 8ae09c7123b32d709baace7f8eb0ad7872f9d7c0..0000000000000000000000000000000000000000 --- a/src/pe/extern/libccd/simplex.h +++ /dev/null @@ -1,104 +0,0 @@ -/*** - * libccd - * --------------------------------- - * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> - * - * - * This file is part of libccd. - * - * Distributed under the OSI-approved BSD License (the "License"); - * see accompanying file BDS-LICENSE for details or see - * <http://www.opensource.org/licenses/bsd-license.php>. - * - * This software is distributed WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the License for more information. - */ - -#ifndef __CCD_SIMPLEX_H__ -#define __CCD_SIMPLEX_H__ - -#include <ccd/compiler.h> -#include "support.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -struct _ccd_simplex_t { - ccd_support_t ps[4]; - int last; //!< index of last added point -}; -typedef struct _ccd_simplex_t ccd_simplex_t; - - -_ccd_inline void ccdSimplexInit(ccd_simplex_t *s); -_ccd_inline int ccdSimplexSize(const ccd_simplex_t *s); -_ccd_inline const ccd_support_t *ccdSimplexLast(const ccd_simplex_t *s); -_ccd_inline const ccd_support_t *ccdSimplexPoint(const ccd_simplex_t *s, int idx); -_ccd_inline ccd_support_t *ccdSimplexPointW(ccd_simplex_t *s, int idx); - -_ccd_inline void ccdSimplexAdd(ccd_simplex_t *s, const ccd_support_t *v); -_ccd_inline void ccdSimplexSet(ccd_simplex_t *s, size_t pos, const ccd_support_t *a); -_ccd_inline void ccdSimplexSetSize(ccd_simplex_t *s, int size); -_ccd_inline void ccdSimplexSwap(ccd_simplex_t *s, size_t pos1, size_t pos2); - - -/**** INLINES ****/ - -_ccd_inline void ccdSimplexInit(ccd_simplex_t *s) -{ - s->last = -1; -} - -_ccd_inline int ccdSimplexSize(const ccd_simplex_t *s) -{ - return s->last + 1; -} - -_ccd_inline const ccd_support_t *ccdSimplexLast(const ccd_simplex_t *s) -{ - return ccdSimplexPoint(s, s->last); -} - -_ccd_inline const ccd_support_t *ccdSimplexPoint(const ccd_simplex_t *s, int idx) -{ - // here is no check on boundaries - return &s->ps[idx]; -} -_ccd_inline ccd_support_t *ccdSimplexPointW(ccd_simplex_t *s, int idx) -{ - return &s->ps[idx]; -} - -_ccd_inline void ccdSimplexAdd(ccd_simplex_t *s, const ccd_support_t *v) -{ - // here is no check on boundaries in sake of speed - ++s->last; - ccdSupportCopy(s->ps + s->last, v); -} - -_ccd_inline void ccdSimplexSet(ccd_simplex_t *s, size_t pos, const ccd_support_t *a) -{ - ccdSupportCopy(s->ps + pos, a); -} - -_ccd_inline void ccdSimplexSetSize(ccd_simplex_t *s, int size) -{ - s->last = size - 1; -} - -_ccd_inline void ccdSimplexSwap(ccd_simplex_t *s, size_t pos1, size_t pos2) -{ - ccd_support_t supp; - - ccdSupportCopy(&supp, &s->ps[pos1]); - ccdSupportCopy(&s->ps[pos1], &s->ps[pos2]); - ccdSupportCopy(&s->ps[pos2], &supp); -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif /* __CCD_SIMPLEX_H__ */ diff --git a/src/pe/extern/libccd/support.c b/src/pe/extern/libccd/support.c deleted file mode 100644 index 6c7f1cc65863be3c974aed1a37df2c9bd3623c50..0000000000000000000000000000000000000000 --- a/src/pe/extern/libccd/support.c +++ /dev/null @@ -1,34 +0,0 @@ -/*** - * libccd - * --------------------------------- - * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> - * - * - * This file is part of libccd. - * - * Distributed under the OSI-approved BSD License (the "License"); - * see accompanying file BDS-LICENSE for details or see - * <http://www.opensource.org/licenses/bsd-license.php>. - * - * This software is distributed WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the License for more information. - */ - -#include "support.h" - -void __ccdSupport(const void *obj1, const void *obj2, - const ccd_vec3_t *_dir, const ccd_t *ccd, - ccd_support_t *supp) -{ - ccd_vec3_t dir; - - ccdVec3Copy(&dir, _dir); - - ccd->support1(obj1, &dir, &supp->v1); - - ccdVec3Scale(&dir, -CCD_ONE); - ccd->support2(obj2, &dir, &supp->v2); - - ccdVec3Sub2(&supp->v, &supp->v1, &supp->v2); -} diff --git a/src/pe/extern/libccd/support.h b/src/pe/extern/libccd/support.h deleted file mode 100644 index 3372f5ef216e6d2c2e834e3dd45b2ec368a88913..0000000000000000000000000000000000000000 --- a/src/pe/extern/libccd/support.h +++ /dev/null @@ -1,55 +0,0 @@ -/*** - * libccd - * --------------------------------- - * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> - * - * - * This file is part of libccd. - * - * Distributed under the OSI-approved BSD License (the "License"); - * see accompanying file BDS-LICENSE for details or see - * <http://www.opensource.org/licenses/bsd-license.php>. - * - * This software is distributed WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the License for more information. - */ - -#ifndef __CCD_SUPPORT_H__ -#define __CCD_SUPPORT_H__ - -#include <ccd/ccd.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -struct _ccd_support_t { - ccd_vec3_t v; //!< Support point in minkowski sum - ccd_vec3_t v1; //!< Support point in obj1 - ccd_vec3_t v2; //!< Support point in obj2 -}; -typedef struct _ccd_support_t ccd_support_t; - -_ccd_inline void ccdSupportCopy(ccd_support_t *, const ccd_support_t *s); - -/** - * Computes support point of obj1 and obj2 in direction dir. - * Support point is returned via supp. - */ -void __ccdSupport(const void *obj1, const void *obj2, - const ccd_vec3_t *dir, const ccd_t *ccd, - ccd_support_t *supp); - - -/**** INLINES ****/ -_ccd_inline void ccdSupportCopy(ccd_support_t *d, const ccd_support_t *s) -{ - *d = *s; -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif /* __CCD_SUPPORT_H__ */ diff --git a/src/pe/extern/libccd/vec3.c b/src/pe/extern/libccd/vec3.c deleted file mode 100644 index f0a331f4fd486a8919dcc23902568cfa3b903540..0000000000000000000000000000000000000000 --- a/src/pe/extern/libccd/vec3.c +++ /dev/null @@ -1,211 +0,0 @@ -/*** - * libccd - * --------------------------------- - * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz> - * - * - * This file is part of libccd. - * - * Distributed under the OSI-approved BSD License (the "License"); - * see accompanying file BDS-LICENSE for details or see - * <http://www.opensource.org/licenses/bsd-license.php>. - * - * This software is distributed WITHOUT ANY WARRANTY; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the License for more information. - */ - -#include <stdio.h> -#include <ccd/vec3.h> -#include "dbg.h" - -static CCD_VEC3(__ccd_vec3_origin, CCD_ZERO, CCD_ZERO, CCD_ZERO); -ccd_vec3_t *ccd_vec3_origin = &__ccd_vec3_origin; - -static ccd_vec3_t points_on_sphere[] = { - CCD_VEC3_STATIC(CCD_REAL( 0.000000), CCD_REAL(-0.000000), CCD_REAL(-1.000000)), - CCD_VEC3_STATIC(CCD_REAL( 0.723608), CCD_REAL(-0.525725), CCD_REAL(-0.447219)), - CCD_VEC3_STATIC(CCD_REAL(-0.276388), CCD_REAL(-0.850649), CCD_REAL(-0.447219)), - CCD_VEC3_STATIC(CCD_REAL(-0.894426), CCD_REAL(-0.000000), CCD_REAL(-0.447216)), - CCD_VEC3_STATIC(CCD_REAL(-0.276388), CCD_REAL( 0.850649), CCD_REAL(-0.447220)), - CCD_VEC3_STATIC(CCD_REAL( 0.723608), CCD_REAL( 0.525725), CCD_REAL(-0.447219)), - CCD_VEC3_STATIC(CCD_REAL( 0.276388), CCD_REAL(-0.850649), CCD_REAL( 0.447220)), - CCD_VEC3_STATIC(CCD_REAL(-0.723608), CCD_REAL(-0.525725), CCD_REAL( 0.447219)), - CCD_VEC3_STATIC(CCD_REAL(-0.723608), CCD_REAL( 0.525725), CCD_REAL( 0.447219)), - CCD_VEC3_STATIC(CCD_REAL( 0.276388), CCD_REAL( 0.850649), CCD_REAL( 0.447219)), - CCD_VEC3_STATIC(CCD_REAL( 0.894426), CCD_REAL( 0.000000), CCD_REAL( 0.447216)), - CCD_VEC3_STATIC(CCD_REAL(-0.000000), CCD_REAL( 0.000000), CCD_REAL( 1.000000)), - CCD_VEC3_STATIC(CCD_REAL( 0.425323), CCD_REAL(-0.309011), CCD_REAL(-0.850654)), - CCD_VEC3_STATIC(CCD_REAL(-0.162456), CCD_REAL(-0.499995), CCD_REAL(-0.850654)), - CCD_VEC3_STATIC(CCD_REAL( 0.262869), CCD_REAL(-0.809012), CCD_REAL(-0.525738)), - CCD_VEC3_STATIC(CCD_REAL( 0.425323), CCD_REAL( 0.309011), CCD_REAL(-0.850654)), - CCD_VEC3_STATIC(CCD_REAL( 0.850648), CCD_REAL(-0.000000), CCD_REAL(-0.525736)), - CCD_VEC3_STATIC(CCD_REAL(-0.525730), CCD_REAL(-0.000000), CCD_REAL(-0.850652)), - CCD_VEC3_STATIC(CCD_REAL(-0.688190), CCD_REAL(-0.499997), CCD_REAL(-0.525736)), - CCD_VEC3_STATIC(CCD_REAL(-0.162456), CCD_REAL( 0.499995), CCD_REAL(-0.850654)), - CCD_VEC3_STATIC(CCD_REAL(-0.688190), CCD_REAL( 0.499997), CCD_REAL(-0.525736)), - CCD_VEC3_STATIC(CCD_REAL( 0.262869), CCD_REAL( 0.809012), CCD_REAL(-0.525738)), - CCD_VEC3_STATIC(CCD_REAL( 0.951058), CCD_REAL( 0.309013), CCD_REAL( 0.000000)), - CCD_VEC3_STATIC(CCD_REAL( 0.951058), CCD_REAL(-0.309013), CCD_REAL( 0.000000)), - CCD_VEC3_STATIC(CCD_REAL( 0.587786), CCD_REAL(-0.809017), CCD_REAL( 0.000000)), - CCD_VEC3_STATIC(CCD_REAL( 0.000000), CCD_REAL(-1.000000), CCD_REAL( 0.000000)), - CCD_VEC3_STATIC(CCD_REAL(-0.587786), CCD_REAL(-0.809017), CCD_REAL( 0.000000)), - CCD_VEC3_STATIC(CCD_REAL(-0.951058), CCD_REAL(-0.309013), CCD_REAL(-0.000000)), - CCD_VEC3_STATIC(CCD_REAL(-0.951058), CCD_REAL( 0.309013), CCD_REAL(-0.000000)), - CCD_VEC3_STATIC(CCD_REAL(-0.587786), CCD_REAL( 0.809017), CCD_REAL(-0.000000)), - CCD_VEC3_STATIC(CCD_REAL(-0.000000), CCD_REAL( 1.000000), CCD_REAL(-0.000000)), - CCD_VEC3_STATIC(CCD_REAL( 0.587786), CCD_REAL( 0.809017), CCD_REAL(-0.000000)), - CCD_VEC3_STATIC(CCD_REAL( 0.688190), CCD_REAL(-0.499997), CCD_REAL( 0.525736)), - CCD_VEC3_STATIC(CCD_REAL(-0.262869), CCD_REAL(-0.809012), CCD_REAL( 0.525738)), - CCD_VEC3_STATIC(CCD_REAL(-0.850648), CCD_REAL( 0.000000), CCD_REAL( 0.525736)), - CCD_VEC3_STATIC(CCD_REAL(-0.262869), CCD_REAL( 0.809012), CCD_REAL( 0.525738)), - CCD_VEC3_STATIC(CCD_REAL( 0.688190), CCD_REAL( 0.499997), CCD_REAL( 0.525736)), - CCD_VEC3_STATIC(CCD_REAL( 0.525730), CCD_REAL( 0.000000), CCD_REAL( 0.850652)), - CCD_VEC3_STATIC(CCD_REAL( 0.162456), CCD_REAL(-0.499995), CCD_REAL( 0.850654)), - CCD_VEC3_STATIC(CCD_REAL(-0.425323), CCD_REAL(-0.309011), CCD_REAL( 0.850654)), - CCD_VEC3_STATIC(CCD_REAL(-0.425323), CCD_REAL( 0.309011), CCD_REAL( 0.850654)), - CCD_VEC3_STATIC(CCD_REAL( 0.162456), CCD_REAL( 0.499995), CCD_REAL( 0.850654)) -}; -ccd_vec3_t *ccd_points_on_sphere = points_on_sphere; -size_t ccd_points_on_sphere_len = sizeof(points_on_sphere) / sizeof(ccd_vec3_t); - - -_ccd_inline ccd_real_t __ccdVec3PointSegmentDist2(const ccd_vec3_t *P, - const ccd_vec3_t *x0, - const ccd_vec3_t *b, - ccd_vec3_t *witness) -{ - // The computation comes from solving equation of segment: - // S(t) = x0 + t.d - // where - x0 is initial point of segment - // - d is direction of segment from x0 (|d| > 0) - // - t belongs to <0, 1> interval - // - // Than, distance from a segment to some point P can be expressed: - // D(t) = |x0 + t.d - P|^2 - // which is distance from any point on segment. Minimization - // of this function brings distance from P to segment. - // Minimization of D(t) leads to simple quadratic equation that's - // solving is straightforward. - // - // Bonus of this method is witness point for free. - - ccd_real_t dist, t; - ccd_vec3_t d, a; - - // direction of segment - ccdVec3Sub2(&d, b, x0); - - // precompute vector from P to x0 - ccdVec3Sub2(&a, x0, P); - - t = -CCD_REAL(1.) * ccdVec3Dot(&a, &d); - t /= ccdVec3Len2(&d); - - if (t < CCD_ZERO || ccdIsZero(t)){ - dist = ccdVec3Dist2(x0, P); - if (witness) - ccdVec3Copy(witness, x0); - }else if (t > CCD_ONE || ccdEq(t, CCD_ONE)){ - dist = ccdVec3Dist2(b, P); - if (witness) - ccdVec3Copy(witness, b); - }else{ - if (witness){ - ccdVec3Copy(witness, &d); - ccdVec3Scale(witness, t); - ccdVec3Add(witness, x0); - dist = ccdVec3Dist2(witness, P); - }else{ - // recycling variables - ccdVec3Scale(&d, t); - ccdVec3Add(&d, &a); - dist = ccdVec3Len2(&d); - } - } - - return dist; -} - -ccd_real_t ccdVec3PointSegmentDist2(const ccd_vec3_t *P, - const ccd_vec3_t *x0, const ccd_vec3_t *b, - ccd_vec3_t *witness) -{ - return __ccdVec3PointSegmentDist2(P, x0, b, witness); -} - -ccd_real_t ccdVec3PointTriDist2(const ccd_vec3_t *P, - const ccd_vec3_t *x0, const ccd_vec3_t *B, - const ccd_vec3_t *C, - ccd_vec3_t *witness) -{ - // Computation comes from analytic expression for triangle (x0, B, C) - // T(s, t) = x0 + s.d1 + t.d2, where d1 = B - x0 and d2 = C - x0 and - // Then equation for distance is: - // D(s, t) = | T(s, t) - P |^2 - // This leads to minimization of quadratic function of two variables. - // The solution from is taken only if s is between 0 and 1, t is - // between 0 and 1 and t + s < 1, otherwise distance from segment is - // computed. - - ccd_vec3_t d1, d2, a; - ccd_real_t u, v, w, p, q, r; - ccd_real_t s, t, dist, dist2; - ccd_vec3_t witness2; - - ccdVec3Sub2(&d1, B, x0); - ccdVec3Sub2(&d2, C, x0); - ccdVec3Sub2(&a, x0, P); - - u = ccdVec3Dot(&a, &a); - v = ccdVec3Dot(&d1, &d1); - w = ccdVec3Dot(&d2, &d2); - p = ccdVec3Dot(&a, &d1); - q = ccdVec3Dot(&a, &d2); - r = ccdVec3Dot(&d1, &d2); - - s = (q * r - w * p) / (w * v - r * r); - t = (-s * r - q) / w; - - if ((ccdIsZero(s) || s > CCD_ZERO) - && (ccdEq(s, CCD_ONE) || s < CCD_ONE) - && (ccdIsZero(t) || t > CCD_ZERO) - && (ccdEq(t, CCD_ONE) || t < CCD_ONE) - && (ccdEq(t + s, CCD_ONE) || t + s < CCD_ONE)){ - - if (witness){ - ccdVec3Scale(&d1, s); - ccdVec3Scale(&d2, t); - ccdVec3Copy(witness, x0); - ccdVec3Add(witness, &d1); - ccdVec3Add(witness, &d2); - - dist = ccdVec3Dist2(witness, P); - }else{ - dist = s * s * v; - dist += t * t * w; - dist += CCD_REAL(2.) * s * t * r; - dist += CCD_REAL(2.) * s * p; - dist += CCD_REAL(2.) * t * q; - dist += u; - } - }else{ - dist = __ccdVec3PointSegmentDist2(P, x0, B, witness); - - dist2 = __ccdVec3PointSegmentDist2(P, x0, C, &witness2); - if (dist2 < dist){ - dist = dist2; - if (witness) - ccdVec3Copy(witness, &witness2); - } - - dist2 = __ccdVec3PointSegmentDist2(P, B, C, &witness2); - if (dist2 < dist){ - dist = dist2; - if (witness) - ccdVec3Copy(witness, &witness2); - } - } - - return dist; -} diff --git a/src/pe/fcd/AnalyticCollisionDetection.h b/src/pe/fcd/AnalyticCollisionDetection.h index 8b6fa28538b785034d8a1e94bf371f6940aeb403..5318eaae9176b0a826447a2b18de1e0a716b4269 100644 --- a/src/pe/fcd/AnalyticCollisionDetection.h +++ b/src/pe/fcd/AnalyticCollisionDetection.h @@ -2124,7 +2124,7 @@ bool collide( Union<BodyTypeTuple>* bd1, BodyB* bd2, Container& container ) bool collision = false; for( auto it=bd1->begin(); it!=bd1->end(); ++it ) { - collision |= SingleCast<BodyTypeTuple, AnalyticSingleCollideFunctor<BodyB, Container>, bool>::execute(*it, func); + collision |= SingleCast<BodyTypeTuple, AnalyticSingleCollideFunctor<BodyB, Container>, bool>::execute(it.getBodyID(), func); } return collision; } @@ -2146,7 +2146,7 @@ bool collide( Union<BodyTypeTupleA>* bd1, Union<BodyTypeTupleB>* bd2, Container& { for( auto it2=bd2->begin(); it2!=bd2->end(); ++it2 ) { - collision |= DoubleCast<BodyTypeTupleA, BodyTypeTupleB, AnalyticCollideFunctor<Container>, bool>::execute(*it1, *it2, func); + collision |= DoubleCast<BodyTypeTupleA, BodyTypeTupleB, AnalyticCollideFunctor<Container>, bool>::execute(it1.getBodyID(), it2.getBodyID(), func); } } return collision; diff --git a/src/pe/fcd/GJKEPACollideFunctor.h b/src/pe/fcd/GJKEPACollideFunctor.h index 84b6d62e4bf58386aae3e2f4b94484647511854c..051d5bcbcace3bb1b99aeb497b789ae4f7895c42 100644 --- a/src/pe/fcd/GJKEPACollideFunctor.h +++ b/src/pe/fcd/GJKEPACollideFunctor.h @@ -115,6 +115,7 @@ namespace gjkepa{ if(gjk.doGJKmargin(*a, *b, margin)){ //2. If collision is possible perform EPA. EPA epa; + epa.useSphereOptimization(true); if(epa.doEPAmargin(*a, *b, gjk, normal, contactPoint, penetrationDepth, margin)){ contacts_.push_back( Contact(a, b, contactPoint, normal, penetrationDepth) ); return true; @@ -168,7 +169,7 @@ namespace gjkepa{ bool collision = false; for( auto it=a->begin(); it!=a->end(); ++it ) { - collision |= SingleCast<BodyTupleA, GJKEPASingleCollideFunctor<BodyB, Container>, bool>::execute(*it, func); + collision |= SingleCast<BodyTupleA, GJKEPASingleCollideFunctor<BodyB, Container>, bool>::execute(it.getBodyID(), func); } return collision; } @@ -186,7 +187,7 @@ namespace gjkepa{ { for( auto it2=b->begin(); it2!=b->end(); ++it2 ) { - collision |= DoubleCast<BodyTupleA, BodyTupleB, GJKEPACollideFunctor<Container>, bool>::execute(*it1, *it2, func); + collision |= DoubleCast<BodyTupleA, BodyTupleB, GJKEPACollideFunctor<Container>, bool>::execute(it1.getBodyID(), it2.getBodyID(), func); } } return collision; @@ -199,7 +200,7 @@ namespace gjkepa{ bool collision = false; for( auto it=a->begin(); it!=a->end(); ++it ) { - collision |= SingleCast<BodyTupleA, GJKEPASingleCollideFunctor<Plane, Container>, bool>::execute(*it, func); + collision |= SingleCast<BodyTupleA, GJKEPASingleCollideFunctor<Plane, Container>, bool>::execute(it.getBodyID(), func); } return collision; } diff --git a/src/pe/raytracing/Color.cpp b/src/pe/raytracing/Color.cpp index 29c7e6d3491eb9c041470474ec6af3c43f784a64..4e9deab3f029827d88226d6ab353d144e33bc165 100644 --- a/src/pe/raytracing/Color.cpp +++ b/src/pe/raytracing/Color.cpp @@ -13,7 +13,7 @@ // You should have received a copy of the GNU General Public License along // with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. // -//! \file Color.cpp +//! \file Color.cpp //! \author Lukas Werner // //====================================================================================================================== diff --git a/src/pe/raytracing/Color.h b/src/pe/raytracing/Color.h index 159c0ef13772b5b01b2dbe18d4beb0f9c9dfd711..cf599930460172403014367436679d9304d194f3 100644 --- a/src/pe/raytracing/Color.h +++ b/src/pe/raytracing/Color.h @@ -13,6 +13,7 @@ // You should have received a copy of the GNU General Public License along // with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. // +//! \file Color.h //! \author Lukas Werner // //====================================================================================================================== @@ -25,6 +26,7 @@ namespace walberla { namespace pe { namespace raytracing { + class Color: public Vector3<real_t> { public: /*!\name Constructors */ @@ -75,6 +77,7 @@ public: static Color colorFromHSV(real_t hue, real_t saturation, real_t value); }; -} -} -} + +} //namespace raytracing +} //namespace pe +} //namespace walberla diff --git a/src/pe/raytracing/Intersects.h b/src/pe/raytracing/Intersects.h index ee889724d55445c9beaadbcac1d675d2e080534d..836ee8dc6af313d2b3b25841900cf61d1a927abc 100644 --- a/src/pe/raytracing/Intersects.h +++ b/src/pe/raytracing/Intersects.h @@ -37,6 +37,7 @@ namespace walberla { namespace pe { namespace raytracing { + inline bool intersects(const SphereID sphere, const Ray& ray, real_t& t, Vec3& n); inline bool intersects(const PlaneID plane, const Ray& ray, real_t& t, Vec3& n); inline bool intersects(const BoxID box, const Ray& ray, real_t& t, Vec3& n); @@ -461,6 +462,7 @@ inline bool intersects(const AABB& aabb, const Ray& ray, real_t& t, real_t paddi t = t_; return true; } -} -} -} + +} //namespace raytracing +} //namespace pe +} //namespace walberla diff --git a/src/pe/raytracing/Lighting.h b/src/pe/raytracing/Lighting.h index ce2778c343b6ad08feae7dc9afbf495ce9d528bc..451cfe3357ca80dad10613a79251ed75da366898 100644 --- a/src/pe/raytracing/Lighting.h +++ b/src/pe/raytracing/Lighting.h @@ -28,6 +28,7 @@ namespace walberla { namespace pe { namespace raytracing { + /*!\brief The Lighting struct defines the properties of a point light in the scene. */ struct Lighting { @@ -71,6 +72,7 @@ struct Lighting { ambientColor = config.getParameter<Color>("ambientColor", Color(0.5,0.5,0.5)); } }; -} -} -} + +} //namespace raytracing +} //namespace pe +} //namespace walberla diff --git a/src/pe/raytracing/Ray.cpp b/src/pe/raytracing/Ray.cpp index 3fbcd307067470b387a2e5511c2fab08605c3afc..c3f0a977684c1ffa0e2171503942572e49460949 100644 --- a/src/pe/raytracing/Ray.cpp +++ b/src/pe/raytracing/Ray.cpp @@ -23,6 +23,7 @@ namespace walberla { namespace pe { namespace raytracing { + /*!\brief Global output operator for rays. * * \param os Reference to the output stream. @@ -35,6 +36,6 @@ std::ostream& operator<<(std::ostream& os, const Ray& ray) { << ", c: (" << ray.getImageX() << "/" << ray.getImageY() << ")>"; } -} -} -} +} //namespace raytracing +} //namespace pe +} //namespace walberla diff --git a/src/pe/raytracing/Ray.h b/src/pe/raytracing/Ray.h index 6fed295fc8a05449b7f30f3c9273852066e847cf..052ee87bf4cd11398d9e3229808068600741eb24 100644 --- a/src/pe/raytracing/Ray.h +++ b/src/pe/raytracing/Ray.h @@ -219,6 +219,7 @@ public: } //@} }; -} -} -} + +} //namespace raytracing +} //namespace pe +} //namespace walberla diff --git a/src/pe/raytracing/Raytracer.cpp b/src/pe/raytracing/Raytracer.cpp index b3793fae2f2c0f72d1f1794fdcf3cec646aeedbb..59320cc4abcb15f6217b53b0e4c1faa03b371dc4 100644 --- a/src/pe/raytracing/Raytracer.cpp +++ b/src/pe/raytracing/Raytracer.cpp @@ -421,6 +421,6 @@ void Raytracer::output(const std::vector<BodyIntersectionInfo>& intersectionsBuf if (tt != NULL) tt->stop("Output"); } -} -} -} +} //namespace raytracing +} //namespace pe +} //namespace walberla diff --git a/src/pe/raytracing/Raytracer.h b/src/pe/raytracing/Raytracer.h index 1bf7b93b1e5e305408d1b94571107463e13ff118..366098150e5f5082439c39e93a157d908f13ecdf 100644 --- a/src/pe/raytracing/Raytracer.h +++ b/src/pe/raytracing/Raytracer.h @@ -37,9 +37,6 @@ #include <stddef.h> -using namespace walberla::pe; -using namespace walberla::timing; - namespace walberla { namespace pe { namespace raytracing { @@ -420,30 +417,37 @@ inline void Raytracer::traceRayInGlobalBodyStorage(const Ray& ray, BodyID& body_ IntersectsFunctor func(ray, t, n); - for(auto bodyIt: *globalBodyStorage_) { - if (!isBodyVisibleFunc_(bodyIt)) { + for(auto bodyIt = globalBodyStorage_->begin(); bodyIt != globalBodyStorage_->end(); ++bodyIt) + { + if (!isBodyVisibleFunc_(bodyIt.getBodyID())) + { continue; } bool isPlane = (bodyIt->getTypeID() == Plane::getStaticTypeID()); - if (isPlane) { - PlaneID plane = (PlaneID)bodyIt; - if (!isPlaneVisible(plane, ray)) { + if (isPlane) + { + PlaneID plane = (PlaneID)bodyIt.getBodyID(); + if (!isPlaneVisible(plane, ray)) + { continue; } } - bool intersects = SingleCast<BodyTypeTuple, IntersectsFunctor, bool>::execute(bodyIt, func); - if (intersects && t < t_closest) { - if (isPlane && confinePlanesToDomain_) { + bool intersects = SingleCast<BodyTypeTuple, IntersectsFunctor, bool>::execute(bodyIt.getBodyID(), func); + if (intersects && t < t_closest) + { + if (isPlane && confinePlanesToDomain_) + { Vec3 intersectionPoint = ray.getOrigin()+ray.getDirection()*t; - if (!forest_->getDomain().contains(intersectionPoint, real_t(1e-8))) { + if (!forest_->getDomain().contains(intersectionPoint, real_t(1e-8))) + { continue; } } // body was shot by ray and is currently closest to camera t_closest = t; - body_closest = bodyIt; + body_closest = bodyIt.getBodyID(); n_closest = n; } } @@ -466,15 +470,15 @@ inline void Raytracer::traceRayNaively(const Ray& ray, BodyID& body_closest, rea for (auto blockIt = forest_->begin(); blockIt != forest_->end(); ++blockIt) { for (auto bodyIt = LocalBodyIterator::begin(*blockIt, storageID_); bodyIt != LocalBodyIterator::end(); ++bodyIt) { - if (!isBodyVisibleFunc_(*bodyIt)) { + if (!isBodyVisibleFunc_(bodyIt.getBodyID())) { continue; } - bool intersects = SingleCast<BodyTypeTuple, IntersectsFunctor, bool>::execute(*bodyIt, func); + bool intersects = SingleCast<BodyTypeTuple, IntersectsFunctor, bool>::execute(bodyIt.getBodyID(), func); if (intersects && t < t_closest) { // body was shot by ray and is currently closest to camera t_closest = t; - body_closest = *bodyIt; + body_closest = bodyIt.getBodyID(); n_closest = n; } } @@ -699,6 +703,7 @@ inline Color Raytracer::getColor(const BodyID body, const Ray& ray, real_t t, co return color; } -} -} -} + +} //namespace raytracing +} //namespace pe +} //namespace walberla diff --git a/src/pe/raytracing/ShadingFunctions.h b/src/pe/raytracing/ShadingFunctions.h index 20f1f9f1fd6098a734784ed21e064f72055348c8..65675bb21aaee1f85688341e064457c5bdfb6954 100644 --- a/src/pe/raytracing/ShadingFunctions.h +++ b/src/pe/raytracing/ShadingFunctions.h @@ -30,6 +30,7 @@ namespace walberla { namespace pe { namespace raytracing { + inline ShadingParameters defaultBodyTypeDependentShadingParams (const BodyID body); inline ShadingParameters processRankDependentShadingParams (const BodyID body); inline ShadingParameters defaultShadingParams (const BodyID body); @@ -169,6 +170,7 @@ inline ShadingParameters violetShadingParams (const BodyID body) { real_t(0)); return s; } -} -} -} + +} //namespace raytracing +} //namespace pe +} //namespace walberla diff --git a/src/pe/raytracing/ShadingParameters.h b/src/pe/raytracing/ShadingParameters.h index 7d0930379729f0e9fd3a127a78bbcf7a4ac478d7..7e476527d1bd665c4017780f8858dbd39aff8876 100644 --- a/src/pe/raytracing/ShadingParameters.h +++ b/src/pe/raytracing/ShadingParameters.h @@ -27,6 +27,7 @@ namespace walberla { namespace pe { namespace raytracing { + struct ShadingParameters { Color diffuseColor; //!< Primary color of the material. Color ambientColor; //!< Color the material has even when its not directly lit. @@ -80,7 +81,8 @@ struct ShadingParameters { return *this; } }; -} -} -} + +} //namespace raytracing +} //namespace pe +} //namespace walberla diff --git a/src/pe/rigidbody/BodyIterators.h b/src/pe/rigidbody/BodyIterators.h index aaf7d7daf55ea5698822197817db048bdebee7a4..5f4ef40fc5bc9be40788c60af43cff52dea9972e 100644 --- a/src/pe/rigidbody/BodyIterators.h +++ b/src/pe/rigidbody/BodyIterators.h @@ -33,104 +33,109 @@ class BodyIterator { public: - template< typename T > - class iterator : public std::iterator< std::input_iterator_tag, typename T::value_type, typename T::difference_type, typename T::pointer, typename T::reference > - { - friend class BodyIterator; - public: - iterator & operator++() { ++it_; checkStateAndAdapt(); return *this; } // prefix ++X - iterator operator++(int) { iterator it( *this ); operator++(); return it; }; // postfix X++ - - bool operator==( const iterator & rhs ) const - { - if (ended_ || rhs.ended_) + template< typename T > + class iterator : public std::iterator< std::input_iterator_tag, typename T::value_type, typename T::difference_type, typename T::pointer, typename T::reference > + { + friend class BodyIterator; + public: + iterator & operator++() { ++it_; checkStateAndAdapt(); return *this; } // prefix ++X + iterator operator++(int) { iterator it( *this ); operator++(); return it; }; // postfix X++ + + bool operator==( const iterator & rhs ) const + { + if (ended_ || rhs.ended_) + { + if (ended_ == rhs.ended_) { - if (ended_ == rhs.ended_) - { - return true; - } - else - { - return false; - } + return true; } - - return it_ == rhs.it_; - } - bool operator!=( const iterator & rhs ) const { return !(*this == rhs); } - - typename T::value_type operator*() { return *it_; } - typename T::pointer operator->() { return *it_; } - - private: - - iterator( const T& begin, - const T& localEnd, - const T& shadowBegin, - const T& shadowEnd ) - : it_(begin) - , itLocalEnd_(localEnd) - , itShadowBegin_(shadowBegin) - , itShadowEnd_(shadowEnd) - , local_(true) - , ended_(false) - { - checkStateAndAdapt(); - } - - iterator( ) - : ended_( true ) - {} - - void checkStateAndAdapt() - { - if( local_ && it_ == itLocalEnd_ ) + else { - it_ = itShadowBegin_; - local_ = false; + return false; } + } - if( it_ == itShadowEnd_ ) - { - ended_ = true; - } - } - - T it_; - T itLocalEnd_; - T itShadowBegin_; - T itShadowEnd_; - - bool local_; - - bool ended_; - }; - - static inline iterator<pe::BodyStorage::Bodies::Iterator> begin( IBlock & block, - const BlockDataID & bodyStorageId) - { - pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId ); - return iterator<pe::BodyStorage::Bodies::Iterator> ( (*storage)[0].begin(), (*storage)[0].end(), (*storage)[1].begin(), (*storage)[1].end() ); - } - - template< typename C > - static inline iterator<pe::BodyStorage::Bodies::CastIterator<C> > begin( IBlock & block, - const BlockDataID & bodyStorageId) - { - pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId ); - return iterator<pe::BodyStorage::Bodies::CastIterator<C> > ( (*storage)[0].begin<C>(), (*storage)[0].end<C>(), (*storage)[1].begin<C>(), (*storage)[1].end<C>() ); - } - - - static inline iterator<pe::BodyStorage::Bodies::Iterator> end() - { - return iterator<pe::BodyStorage::Bodies::Iterator> ( ); - } - template< typename C > - static inline iterator<pe::BodyStorage::Bodies::CastIterator<C> > end() - { - return iterator<pe::BodyStorage::Bodies::CastIterator<C> > ( ); - } + //std::vector::iterator cannot be compared between different instances (assert!) + if (local_ == rhs.local_) + return it_ == rhs.it_; + else + return false; + } + bool operator!=( const iterator & rhs ) const { return !(*this == rhs); } + + typename T::reference operator*() { return *it_; } + typename T::pointer operator->() { return it_.operator->(); } + typename T::pointer getBodyID() { return it_.getBodyID(); } + + private: + + iterator( const T& begin, + const T& localEnd, + const T& shadowBegin, + const T& shadowEnd ) + : it_(begin) + , itLocalEnd_(localEnd) + , itShadowBegin_(shadowBegin) + , itShadowEnd_(shadowEnd) + , local_(true) + , ended_(false) + { + checkStateAndAdapt(); + } + + iterator( ) + : ended_( true ) + {} + + void checkStateAndAdapt() + { + if( local_ && it_ == itLocalEnd_ ) + { + it_ = itShadowBegin_; + local_ = false; + } + + if( !local_ && it_ == itShadowEnd_ ) + { + ended_ = true; + } + } + + T it_; + T itLocalEnd_; + T itShadowBegin_; + T itShadowEnd_; + + bool local_; //!< still in local storage? + + bool ended_; + }; + + static inline iterator<pe::BodyStorage::iterator> begin( IBlock & block, + const BlockDataID & bodyStorageId) + { + pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId ); + return iterator<pe::BodyStorage::iterator> ( (*storage)[0].begin(), (*storage)[0].end(), (*storage)[1].begin(), (*storage)[1].end() ); + } + + template< typename C > + static inline iterator<pe::BodyStorage::cast_iterator<C> > begin( IBlock & block, + const BlockDataID & bodyStorageId) + { + pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId ); + return iterator<pe::BodyStorage::cast_iterator<C> > ( (*storage)[0].begin<C>(), (*storage)[0].end<C>(), (*storage)[1].begin<C>(), (*storage)[1].end<C>() ); + } + + + static inline iterator<pe::BodyStorage::iterator> end() + { + return iterator<pe::BodyStorage::iterator> ( ); + } + template< typename C > + static inline iterator<pe::BodyStorage::cast_iterator<C> > end() + { + return iterator<pe::BodyStorage::cast_iterator<C> > ( ); + } }; // class BodyIterator @@ -140,87 +145,88 @@ class LocalBodyIterator { public: - template< typename T > - class iterator : public std::iterator< std::input_iterator_tag, typename T::value_type, typename T::difference_type, typename T::pointer, typename T::reference > - { - friend class LocalBodyIterator; - public: - iterator & operator++() { ++it_; checkStateAndAdapt(); return *this; } // prefix ++X - iterator operator++(int) { iterator it( *this ); operator++(); return it; }; // postfix X++ - - bool operator==( const iterator & rhs ) const - { - if (ended_ || rhs.ended_) + template< typename T > + class iterator : public std::iterator< std::input_iterator_tag, typename T::value_type, typename T::difference_type, typename T::pointer, typename T::reference > + { + friend class LocalBodyIterator; + public: + iterator & operator++() { ++it_; checkStateAndAdapt(); return *this; } // prefix ++X + iterator operator++(int) { iterator it( *this ); operator++(); return it; }; // postfix X++ + + bool operator==( const iterator & rhs ) const + { + if (ended_ || rhs.ended_) + { + if (ended_ == rhs.ended_) { - if (ended_ == rhs.ended_) - { - return true; - } - else - { - return false; - } + return true; } - - return it_ == rhs.it_; - } - bool operator!=( const iterator & rhs ) const { return !(*this == rhs); } - - typename T::value_type operator*() { return *it_; } - typename T::pointer operator->() { return *it_; } - - private: - - iterator( const T& begin, - const T& end ) - : it_(begin), itEnd_(end), ended_( false ) - { - checkStateAndAdapt(); - } - - iterator( ) - : ended_( true ) - {} - - void checkStateAndAdapt() - { - if( it_ == itEnd_ ) + else { - ended_ = true; + return false; } - } - - T it_; - T itEnd_; - - bool ended_; - }; - - static inline iterator<pe::BodyStorage::Bodies::Iterator> begin( IBlock & block, - const BlockDataID & bodyStorageId) - { - pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId ); - return iterator<pe::BodyStorage::Bodies::Iterator> ( (*storage)[0].begin(), (*storage)[0].end() ); - } - - template< typename C > - static inline iterator<pe::BodyStorage::Bodies::CastIterator<C> > begin( IBlock & block, - const BlockDataID & bodyStorageId) - { - pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId ); - return iterator<pe::BodyStorage::Bodies::CastIterator<C> > ( (*storage)[0].begin<C>(), (*storage)[0].end<C>() ); - } - - - static inline iterator<pe::BodyStorage::Bodies::Iterator> end() - { - return iterator<pe::BodyStorage::Bodies::Iterator> ( ); - } - template< typename C > - static inline iterator<pe::BodyStorage::Bodies::CastIterator<C> > end() - { - return iterator<pe::BodyStorage::Bodies::CastIterator<C> > ( ); - } + } + + return it_ == rhs.it_; + } + bool operator!=( const iterator & rhs ) const { return !(*this == rhs); } + + typename T::reference operator*() { return *it_; } + typename T::pointer operator->() { return it_.operator->(); } + typename T::pointer getBodyID() { return it_.getBodyID(); } + + private: + + iterator( const T& begin, + const T& end ) + : it_(begin), itEnd_(end), ended_( false ) + { + checkStateAndAdapt(); + } + + iterator( ) + : ended_( true ) + {} + + void checkStateAndAdapt() + { + if( it_ == itEnd_ ) + { + ended_ = true; + } + } + + T it_; + T itEnd_; + + bool ended_; + }; + + static inline iterator<pe::BodyStorage::iterator> begin( IBlock & block, + const BlockDataID & bodyStorageId) + { + pe::BodyStorage& storage = (*block.getData< pe::Storage >( bodyStorageId ))[0]; + return iterator<pe::BodyStorage::iterator> ( storage.begin(), storage.end() ); + } + + template< typename C > + static inline iterator<pe::BodyStorage::cast_iterator<C> > begin( IBlock & block, + const BlockDataID & bodyStorageId) + { + pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId ); + return iterator<pe::BodyStorage::cast_iterator<C> > ( (*storage)[0].begin<C>(), (*storage)[0].end<C>() ); + } + + + static inline iterator<pe::BodyStorage::iterator> end() + { + return iterator<pe::BodyStorage::iterator> ( ); + } + template< typename C > + static inline iterator<pe::BodyStorage::cast_iterator<C> > end() + { + return iterator<pe::BodyStorage::cast_iterator<C> > ( ); + } }; // class LocalBodyIterator @@ -229,87 +235,88 @@ class ShadowBodyIterator { public: - template< typename T > - class iterator : public std::iterator< std::input_iterator_tag, typename T::value_type, typename T::difference_type, typename T::pointer, typename T::reference > - { - friend class ShadowBodyIterator; - public: - iterator & operator++() { ++it_; checkStateAndAdapt(); return *this; } // prefix ++X - iterator operator++(int) { iterator it( *this ); operator++(); return it; }; // postfix X++ - - bool operator==( const iterator & rhs ) const - { - if (ended_ || rhs.ended_) + template< typename T > + class iterator : public std::iterator< std::input_iterator_tag, typename T::value_type, typename T::difference_type, typename T::pointer, typename T::reference > + { + friend class ShadowBodyIterator; + public: + iterator & operator++() { ++it_; checkStateAndAdapt(); return *this; } // prefix ++X + iterator operator++(int) { iterator it( *this ); operator++(); return it; }; // postfix X++ + + bool operator==( const iterator & rhs ) const + { + if (ended_ || rhs.ended_) + { + if (ended_ == rhs.ended_) { - if (ended_ == rhs.ended_) - { - return true; - } - else - { - return false; - } + return true; } - - return it_ == rhs.it_; - } - bool operator!=( const iterator & rhs ) const { return !(*this == rhs); } - - typename T::value_type operator*() { return *it_; } - typename T::pointer operator->() { return *it_; } - - private: - - iterator( const T& begin, - const T& end ) - : it_(begin), itEnd_(end), ended_( false ) - { - checkStateAndAdapt(); - } - - iterator( ) - : ended_( true ) - {} - - void checkStateAndAdapt() - { - if( it_ == itEnd_ ) + else { - ended_ = true; + return false; } - } - - T it_; - T itEnd_; - - bool ended_; - }; - - static inline iterator<pe::BodyStorage::Bodies::Iterator> begin( IBlock & block, - const BlockDataID & bodyStorageId) - { - pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId ); - return iterator<pe::BodyStorage::Bodies::Iterator> ( (*storage)[1].begin(), (*storage)[1].end() ); - } - - template< typename C > - static inline iterator<pe::BodyStorage::Bodies::CastIterator<C> > begin( IBlock & block, - const BlockDataID & bodyStorageId) - { - pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId ); - return iterator<pe::BodyStorage::Bodies::CastIterator<C> > ( (*storage)[1].begin<C>(), (*storage)[1].end<C>() ); - } - - - static inline iterator<pe::BodyStorage::Bodies::Iterator> end() - { - return iterator<pe::BodyStorage::Bodies::Iterator> ( ); - } - template< typename C > - static inline iterator<pe::BodyStorage::Bodies::CastIterator<C> > end() - { - return iterator<pe::BodyStorage::Bodies::CastIterator<C> > ( ); - } + } + + return it_ == rhs.it_; + } + bool operator!=( const iterator & rhs ) const { return !(*this == rhs); } + + typename T::reference operator*() { return *it_; } + typename T::pointer operator->() { return it_.operator->(); } + typename T::pointer getBodyID() { return it_.getBodyID(); } + + private: + + iterator( const T& begin, + const T& end ) + : it_(begin), itEnd_(end), ended_( false ) + { + checkStateAndAdapt(); + } + + iterator( ) + : ended_( true ) + {} + + void checkStateAndAdapt() + { + if( it_ == itEnd_ ) + { + ended_ = true; + } + } + + T it_; + T itEnd_; + + bool ended_; + }; + + static inline iterator<pe::BodyStorage::iterator> begin( IBlock & block, + const BlockDataID & bodyStorageId) + { + pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId ); + return iterator<pe::BodyStorage::iterator> ( (*storage)[1].begin(), (*storage)[1].end() ); + } + + template< typename C > + static inline iterator<pe::BodyStorage::cast_iterator<C> > begin( IBlock & block, + const BlockDataID & bodyStorageId) + { + pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId ); + return iterator<pe::BodyStorage::cast_iterator<C> > ( (*storage)[1].begin<C>(), (*storage)[1].end<C>() ); + } + + + static inline iterator<pe::BodyStorage::iterator> end() + { + return iterator<pe::BodyStorage::iterator> ( ); + } + template< typename C > + static inline iterator<pe::BodyStorage::cast_iterator<C> > end() + { + return iterator<pe::BodyStorage::cast_iterator<C> > ( ); + } }; // class ShadowBodyIterator diff --git a/src/pe/rigidbody/BodyStorage.h b/src/pe/rigidbody/BodyStorage.h index 0ab0ef40b58ab71e2712d2de3132e2ad388baa66..7e4475e9a7ab8dfd8e19730ae27ee141391a15f3 100644 --- a/src/pe/rigidbody/BodyStorage.h +++ b/src/pe/rigidbody/BodyStorage.h @@ -26,25 +26,22 @@ // Includes //************************************************************************************************* -#include <algorithm> -#include <functional> -#include <map> -#include <vector> #include <core/NonCopyable.h> #include <core/debug/Debug.h> -#include <core/ptrvector/policies/PtrDelete.h> -#include <core/ptrvector/PtrVector.h> #include <pe/rigidbody/RigidBody.h> +#include <pe/rigidbody/RigidBodyCastIterator.h> +#include <pe/rigidbody/RigidBodyIterator.h> #include <pe/Types.h> +#include <algorithm> #include <functional> +#include <map> +#include <memory> +#include <vector> namespace walberla { namespace pe { - - - //================================================================================================= // // CLASS DEFINITION @@ -62,13 +59,18 @@ class BodyStorage : private NonCopyable public: //**Type definitions**************************************************************************** //! Container for the bodies contained in the simulation world. - typedef PtrVector<BodyType, PtrDelete> Bodies; + using VectorContainer = std::vector< std::unique_ptr<RigidBody> >; + using ConstVectorContainer = std::vector< std::unique_ptr<const RigidBody> >; //********************************************************************************************** //**Type definitions**************************************************************************** - typedef Bodies::SizeType SizeType; //!< Size type of the body storage. - typedef Bodies::Iterator Iterator; //!< Iterator over non-const bodies. - typedef Bodies::ConstIterator ConstIterator; //!< Iterator over constant bodies. + using size_type = VectorContainer::size_type; //!< Size type of the body storage. + using iterator = RigidBodyIterator; //!< Iterator over non-const bodies. + using const_iterator = ConstRigidBodyIterator; //!< Iterator over constant bodies. + template <typename C> //cast type + using cast_iterator = RigidBodyCastIterator<C>; + template <typename C> //cast type + using const_cast_iterator = ConstRigidBodyCastIterator<C>; //********************************************************************************************** //**Constructors******************************************************************************** @@ -88,45 +90,58 @@ public: //**Utility functions*************************************************************************** /*!\name Utility functions */ //@{ - inline bool isEmpty () const; - inline SizeType size () const; - template< typename T > - inline SizeType size () const; - inline Iterator begin (); - inline ConstIterator begin () const; - template< typename T > - inline typename Bodies::template CastIterator<T> begin(); - template< typename T > - inline typename Bodies::template ConstCastIterator<T> begin() const; - inline Iterator end (); - inline ConstIterator end () const; - template< typename T > - inline typename Bodies::template CastIterator<T> end(); - template< typename T > - inline typename Bodies::template ConstCastIterator<T> end() const; - inline BodyID at ( SizeType index ); - inline ConstBodyID at ( SizeType index ) const; - inline Iterator find ( id_t sid ); - inline ConstIterator find ( id_t sid ) const; - inline Iterator find ( ConstBodyID body ); - inline ConstIterator find ( ConstBodyID body ) const; - inline void validate(); + inline bool isEmpty () const; + inline size_type size () const; + + inline iterator begin (); + inline const_iterator begin () const; + inline const_iterator cbegin () const; + inline iterator end (); + inline const_iterator end () const; + inline const_iterator cend () const; + + template< typename C > + inline cast_iterator<C> begin(); + template< typename C > + inline const_cast_iterator<C> begin() const; + template< typename C > + inline const_cast_iterator<C> cbegin() const; + template< typename C > + inline cast_iterator<C> end(); + template< typename C > + inline const_cast_iterator<C> end() const; + template< typename C > + inline const_cast_iterator<C> cend() const; + + inline RigidBody& front(); + inline const RigidBody& front() const; + inline RigidBody& back(); + inline const RigidBody& back() const; + + inline BodyID at ( size_type index ); + inline ConstBodyID at ( size_type index ) const; + inline iterator find ( id_t sid ); + inline const_iterator find ( id_t sid ) const; + inline iterator find ( ConstBodyID body ); + inline const_iterator find ( ConstBodyID body ) const; + inline void validate(); //@} //********************************************************************************************** //**Add/Remove functions************************************************************************ /*!\name Add/Remove functions */ //@{ - inline void add ( BodyID body ); - inline void remove ( const id_t sid ); - inline void remove ( BodyID body ); - inline ConstIterator remove ( ConstIterator pos ); - inline Iterator remove ( Iterator pos ); - inline void release ( const id_t sid ); - inline void release ( BodyID body ); - inline ConstIterator release ( ConstIterator pos ); - inline Iterator release ( Iterator pos ); - inline void clear (); + [[deprecated]] inline RigidBody& add ( BodyID body ); + inline RigidBody& add ( std::unique_ptr<RigidBody>&& body ); + inline iterator remove ( const id_t sid ); + inline iterator remove ( BodyID body ); + inline const_iterator remove ( const_iterator pos ); + inline iterator remove ( iterator pos ); + inline std::unique_ptr<RigidBody> release ( const id_t sid ); + inline std::unique_ptr<RigidBody> release ( BodyID body ); + inline std::unique_ptr<RigidBody> release ( const_iterator& pos ); + inline std::unique_ptr<RigidBody> release ( iterator& pos ); + inline void clear (); //@} //********************************************************************************************** @@ -147,8 +162,8 @@ private: //**Member variables**************************************************************************** /*!\name Member variables */ //@{ - Bodies bodies_; //!< The rigid bodies contained in the simulation world. - std::map<id_t, SizeType> bodyIDs_; //!< The association of system IDs to rigid bodies. + VectorContainer bodies_; //!< The rigid bodies contained in the simulation world. + std::map<id_t, size_type> bodyIDs_; //!< The association of system IDs to rigid bodies. std::map< std::string, std::function<void (BodyID)> > addCallbacks_; std::map< std::string, std::function<void (BodyID)> > removeCallbacks_; @@ -170,9 +185,9 @@ private: /*!\brief The standard constructor. */ inline BodyStorage::BodyStorage() - : bodies_( 1000 ) - , bodyIDs_() + : bodyIDs_() { + bodies_.reserve(1000); } //************************************************************************************************* @@ -195,7 +210,7 @@ inline BodyStorage::~BodyStorage() { WALBERLA_ASSERT_EQUAL(addCallbacks_.size(), 0, "Still add callbacks registered!"); WALBERLA_ASSERT_EQUAL(removeCallbacks_.size(), 0, "Still remove callbacks registered!"); - clear(); + clear(); } //************************************************************************************************* @@ -216,7 +231,7 @@ inline BodyStorage::~BodyStorage() inline bool BodyStorage::isEmpty() const { - return bodies_.isEmpty(); + return bodies_.empty(); } //************************************************************************************************* @@ -227,7 +242,7 @@ inline bool BodyStorage::isEmpty() const * \return The number of rigid bodies. */ -inline BodyStorage::SizeType BodyStorage::size() const +inline BodyStorage::size_type BodyStorage::size() const { return bodies_.size(); } @@ -235,33 +250,27 @@ inline BodyStorage::SizeType BodyStorage::size() const //************************************************************************************************* -/*!\brief Returns the number of rigid bodies of type \a T contained in the body storage. - * - * \return The number of rigid bodies of type \a T. +/*!\brief Returns an iterator to the first contained rigid body. * - * \b Note: The total number of objects of type \a T is not cached but recalculated each time the - * function is called. Using the templated version of size() to calculate the total number objects - * of type \a T is therefore more expensive than using the non-template version of size() to get - * the total number of pointers in the vector! + * \return Iterator to the first contained rigid body. */ -template< typename T > // Cast type -inline BodyStorage::SizeType BodyStorage::size() const +inline BodyStorage::iterator BodyStorage::begin() { - return bodies_.template size<T>(); + return BodyStorage::iterator(bodies_.begin()); } //************************************************************************************************* //************************************************************************************************* -/*!\brief Returns an iterator to the first contained rigid body. +/*!\brief Returns a constant iterator to the first contained rigid body. * - * \return Iterator to the first contained rigid body. + * \return Constant iterator to the first contained rigid body. */ -inline BodyStorage::Iterator BodyStorage::begin() +inline BodyStorage::const_iterator BodyStorage::begin() const { - return bodies_.begin(); + return cbegin(); } //************************************************************************************************* @@ -272,9 +281,48 @@ inline BodyStorage::Iterator BodyStorage::begin() * \return Constant iterator to the first contained rigid body. */ -inline BodyStorage::ConstIterator BodyStorage::begin() const +inline BodyStorage::const_iterator BodyStorage::cbegin() const +{ + return BodyStorage::const_iterator(bodies_.cbegin()); +} +//************************************************************************************************* + + +//************************************************************************************************* +/*!\brief Returns an iterator just past the last contained rigid body. + * + * \return Iterator just past the last contained rigid body. + */ + +inline BodyStorage::iterator BodyStorage::end() +{ + return BodyStorage::iterator(bodies_.end()); +} +//************************************************************************************************* + + +//************************************************************************************************* +/*!\brief Returns a constant iterator just past the last contained rigid body. + * + * \return Constant iterator just past the last contained rigid body. + */ + +inline BodyStorage::const_iterator BodyStorage::end() const +{ + return cend(); +} +//************************************************************************************************* + + +//************************************************************************************************* +/*!\brief Returns a constant iterator just past the last contained rigid body. + * + * \return Constant iterator just past the last contained rigid body. + */ + +inline BodyStorage::const_iterator BodyStorage::cend() const { - return bodies_.begin(); + return BodyStorage::const_iterator(bodies_.cend()); } //************************************************************************************************* @@ -285,10 +333,10 @@ inline BodyStorage::ConstIterator BodyStorage::begin() const * \return Iterator to the first contained rigid body. */ -template< typename T > // Cast Type -inline BodyStorage::Bodies::template CastIterator<T> BodyStorage::begin() +template< typename C > // Cast Type +inline BodyStorage::cast_iterator<C> BodyStorage::begin() { - return bodies_.template begin<T>(); + return BodyStorage::cast_iterator<C>(bodies_.begin(), bodies_.end()); } //************************************************************************************************* @@ -299,50 +347,52 @@ inline BodyStorage::Bodies::template CastIterator<T> BodyStorage::begin() * \return Constant iterator to the first contained rigid body. */ -template< typename T > // Cast Type -inline BodyStorage::Bodies::template ConstCastIterator<T> BodyStorage::begin() const +template< typename C > // Cast Type +inline BodyStorage::const_cast_iterator<C> BodyStorage::begin() const { - return bodies_.template begin<T>(); + return cbegin(); } //************************************************************************************************* //************************************************************************************************* -/*!\brief Returns an iterator just past the last contained rigid body. +/*!\brief Returns a constant iterator to the first contained rigid body. * - * \return Iterator just past the last contained rigid body. + * \return Constant iterator to the first contained rigid body. */ -inline BodyStorage::Iterator BodyStorage::end() +template< typename C > // Cast Type +inline BodyStorage::const_cast_iterator<C> BodyStorage::cbegin() const { - return bodies_.end(); + return BodyStorage::const_cast_iterator<C>(bodies_.begin(), bodies_.end()); } //************************************************************************************************* //************************************************************************************************* -/*!\brief Returns a constant iterator just past the last contained rigid body. +/*!\brief Returns an iterator just past the last contained rigid body. * - * \return Constant iterator just past the last contained rigid body. + * \return Iterator just past the last contained rigid body. */ -inline BodyStorage::ConstIterator BodyStorage::end() const +template< typename C > // Cast Type +inline BodyStorage::cast_iterator<C> BodyStorage::end() { - return bodies_.end(); + return BodyStorage::cast_iterator<C>(bodies_.end(), bodies_.end()); } //************************************************************************************************* //************************************************************************************************* -/*!\brief Returns an iterator just past the last contained rigid body. +/*!\brief Returns a constant iterator just past the last contained rigid body. * - * \return Iterator just past the last contained rigid body. + * \return Constant iterator just past the last contained rigid body. */ -template< typename T > // Cast Type -inline BodyStorage::Bodies::template CastIterator<T> BodyStorage::end() +template< typename C > // Cast Type +inline BodyStorage::const_cast_iterator<C> BodyStorage::end() const { - return bodies_.template end<T>(); + return cend(); } //************************************************************************************************* @@ -353,13 +403,30 @@ inline BodyStorage::Bodies::template CastIterator<T> BodyStorage::end() * \return Constant iterator just past the last contained rigid body. */ -template< typename T > // Cast Type -inline BodyStorage::Bodies::template ConstCastIterator<T> BodyStorage::end() const +template< typename C > // Cast Type +inline BodyStorage::const_cast_iterator<C> BodyStorage::cend() const { - return bodies_.template end<T>(); + return BodyStorage::const_cast_iterator<C>(bodies_.end(), bodies_.end()); } //************************************************************************************************* +inline RigidBody& BodyStorage::front() +{ + return *bodies_.front(); +} +inline const RigidBody& BodyStorage::front() const +{ + return *bodies_.front(); +} +inline RigidBody& BodyStorage::back() +{ + return *bodies_.back(); +} +inline const RigidBody& BodyStorage::back() const +{ + return *bodies_.back(); +} + //************************************************************************************************* /*!\brief Returns a handle to the indexed rigid body. @@ -370,10 +437,10 @@ inline BodyStorage::Bodies::template ConstCastIterator<T> BodyStorage::end() con * \b Note: No runtime check is performed to ensure the validity of the access index. */ -inline BodyID BodyStorage::at( SizeType index ) +inline BodyID BodyStorage::at( size_type index ) { WALBERLA_ASSERT( index < size(), "Invalid body index" ); - return bodies_[index]; + return bodies_[index].get(); } //************************************************************************************************* @@ -387,10 +454,10 @@ inline BodyID BodyStorage::at( SizeType index ) * \b Note: No runtime check is performed to ensure the validity of the access index. */ -inline ConstBodyID BodyStorage::at( SizeType index ) const +inline ConstBodyID BodyStorage::at( size_type index ) const { WALBERLA_ASSERT( index < size(), "Invalid body index" ); - return bodies_[index]; + return bodies_[index].get(); } //************************************************************************************************* @@ -406,13 +473,13 @@ inline ConstBodyID BodyStorage::at( SizeType index ) const * iterator just past the end of the last body contained in the body storage. */ -inline BodyStorage::Iterator BodyStorage::find( id_t sid ) +inline BodyStorage::iterator BodyStorage::find( id_t sid ) { - std::map<id_t, SizeType>::const_iterator pos = bodyIDs_.find( sid ); + std::map<id_t, size_type>::const_iterator pos = bodyIDs_.find( sid ); if( pos == bodyIDs_.end() ) - return bodies_.end(); + return BodyStorage::iterator(bodies_.end()); - return bodies_.begin() + static_cast<Bodies::Iterator::difference_type>(pos->second); + return BodyStorage::iterator(bodies_.begin() + static_cast<VectorContainer::iterator::difference_type>(pos->second)); } //************************************************************************************************* @@ -428,13 +495,13 @@ inline BodyStorage::Iterator BodyStorage::find( id_t sid ) * a constant iterator just past the end of the last body contained in the body storage. */ -inline BodyStorage::ConstIterator BodyStorage::find( id_t sid ) const +inline BodyStorage::const_iterator BodyStorage::find( id_t sid ) const { - std::map<id_t, SizeType>::const_iterator pos = bodyIDs_.find( sid ); + std::map<id_t, size_type>::const_iterator pos = bodyIDs_.find( sid ); if( pos == bodyIDs_.end() ) - return bodies_.end(); + return BodyStorage::const_iterator(bodies_.end()); - return bodies_.begin() + static_cast<Bodies::Iterator::difference_type>(pos->second); + return BodyStorage::const_iterator(bodies_.begin() + static_cast<VectorContainer::iterator::difference_type>(pos->second)); } //************************************************************************************************* @@ -450,9 +517,9 @@ inline BodyStorage::ConstIterator BodyStorage::find( id_t sid ) const * just past the end of the last body contained in the body storage. */ -inline BodyStorage::Iterator BodyStorage::find( ConstBodyID body ) +inline BodyStorage::iterator BodyStorage::find( ConstBodyID body ) { - return find( body->getSystemID() ); + return BodyStorage::iterator(find( body->getSystemID() )); } //************************************************************************************************* @@ -468,9 +535,9 @@ inline BodyStorage::Iterator BodyStorage::find( ConstBodyID body ) * constant iterator just past the end of the last body contained in the body storage. */ -inline BodyStorage::ConstIterator BodyStorage::find( ConstBodyID body ) const +inline BodyStorage::const_iterator BodyStorage::find( ConstBodyID body ) const { - return find( body->getSystemID() ); + return BodyStorage::const_iterator(find( body->getSystemID() )); } //************************************************************************************************* @@ -494,16 +561,45 @@ inline BodyStorage::ConstIterator BodyStorage::find( ConstBodyID body ) const * logarithmic unless reallocation occurs. */ -inline void BodyStorage::add( BodyID body ) +inline RigidBody& BodyStorage::add( BodyID body ) { WALBERLA_ASSERT( bodyIDs_.find( body->getSystemID() ) == bodyIDs_.end(), "Body with same system ID already added." ); bodyIDs_[ body->getSystemID() ] = bodies_.size(); - bodies_.pushBack( body ); + bodies_.push_back( std::unique_ptr<RigidBody>(body) ); for (auto it = addCallbacks_.begin(); it != addCallbacks_.end(); ++it) { - it->second(body); + it->second(bodies_.back().get()); } + + return *bodies_.back(); +} +//************************************************************************************************* + + +//************************************************************************************************* +/*!\brief Adding a rigid body to the body storage. + * + * \param body The new rigid body to be added to the body storage. + * \return void + * + * This function adds a rigid body to the body storage. Adding bodies with non-unique system ID or + * adding the same body multiple times results in undefined behaviour. The time complexity is + * logarithmic unless reallocation occurs. + */ + +inline RigidBody& BodyStorage::add( std::unique_ptr<RigidBody>&& body ) +{ + WALBERLA_ASSERT( bodyIDs_.find( body->getSystemID() ) == bodyIDs_.end(), "Body with same system ID already added." ); + bodyIDs_[ body->getSystemID() ] = bodies_.size(); + bodies_.push_back( std::move(body) ); + + for (auto it = addCallbacks_.begin(); it != addCallbacks_.end(); ++it) + { + it->second(bodies_.back().get()); + } + + return *bodies_.back(); } //************************************************************************************************* @@ -520,23 +616,25 @@ inline void BodyStorage::add( BodyID body ) * The last element is swapped to the actual position and the length is reduced by one. */ -inline void BodyStorage::remove( const id_t sid ) +inline +BodyStorage::iterator BodyStorage::remove( const id_t sid ) { - std::map<id_t, SizeType>::iterator it = bodyIDs_.find( sid ); + std::map<id_t, size_type>::iterator it = bodyIDs_.find( sid ); WALBERLA_ASSERT( it != bodyIDs_.end(), "The body's system ID was not registered." ); // Move last element to deleted place and update the system ID to index mapping. - SizeType i = it->second; + size_type i = it->second; for (auto cb = removeCallbacks_.begin(); cb != removeCallbacks_.end(); ++cb) { - cb->second( bodies_[i] ); + cb->second( bodies_[i].get() ); } bodyIDs_[ bodies_.back()->getSystemID() ] = i; std::swap( bodies_[i], bodies_.back() ); bodyIDs_.erase( it ); - bodies_.popBack(); + bodies_.pop_back(); + return iterator(bodies_.begin() + int_c(i)); } //************************************************************************************************* @@ -552,10 +650,9 @@ inline void BodyStorage::remove( const id_t sid ) * the element to be removed. The time complexity is logarithmic unless reallocation occurs. */ -inline BodyStorage::ConstIterator BodyStorage::remove( ConstIterator pos ) +inline BodyStorage::const_iterator BodyStorage::remove( const_iterator pos ) { - remove( (*pos)->getSystemID() ); - return pos; + return remove( pos->getSystemID() ); } //************************************************************************************************* @@ -571,10 +668,9 @@ inline BodyStorage::ConstIterator BodyStorage::remove( ConstIterator pos ) * the element to be removed. The time complexity is logarithmic unless reallocation occurs. */ -inline BodyStorage::Iterator BodyStorage::remove( Iterator pos ) +inline BodyStorage::iterator BodyStorage::remove( iterator pos ) { - remove( (*pos)->getSystemID() ); - return pos; + return remove( pos->getSystemID() ); } //************************************************************************************************* @@ -590,9 +686,10 @@ inline BodyStorage::Iterator BodyStorage::remove( Iterator pos ) * the element to be removed. The time complexity is logarithmic unless reallocation occurs. */ -inline void BodyStorage::remove( BodyID body ) +inline +BodyStorage::iterator BodyStorage::remove( BodyID body ) { - remove( body->getSystemID() ); + return remove( body->getSystemID() ); } //************************************************************************************************* @@ -609,23 +706,22 @@ inline void BodyStorage::remove( BodyID body ) * Last element is swapped to the actual position and length is reduced by 1. */ -inline void BodyStorage::release( const id_t sid ) +inline std::unique_ptr<RigidBody> BodyStorage::release( const id_t sid ) { - std::map<id_t, SizeType>::iterator it = bodyIDs_.find( sid ); + std::map<id_t, size_type>::iterator it = bodyIDs_.find( sid ); WALBERLA_ASSERT( it != bodyIDs_.end(), "The body's system ID was not registered." ); // Move last element to deleted place and update the system ID to index mapping. - SizeType i = it->second; + size_type i = it->second; - for (auto cb = removeCallbacks_.begin(); cb != removeCallbacks_.end(); ++cb) - { - cb->second( bodies_[i] ); - } + std::for_each(removeCallbacks_.begin(), removeCallbacks_.end(), [&](auto& cb){cb.second( bodies_[i].get() );}); bodyIDs_[ bodies_.back()->getSystemID() ] = i; std::swap( bodies_[i], bodies_.back() ); bodyIDs_.erase( it ); - bodies_.releaseBack(); + auto tmp = std::move(bodies_.back()); + bodies_.pop_back(); + return tmp; } //************************************************************************************************* @@ -641,10 +737,12 @@ inline void BodyStorage::release( const id_t sid ) * the element to be released. The time complexity is logarithmic unless reallocation occurs. */ -inline BodyStorage::ConstIterator BodyStorage::release( ConstIterator pos ) +inline std::unique_ptr<RigidBody> BodyStorage::release( const_iterator& pos ) { - release( (*pos)->getSystemID() ); - return pos; + auto diff = std::distance(bodies_.cbegin(), pos.get()); + auto tmp = release( pos->getSystemID() ); + pos = const_iterator(bodies_.begin() + diff); + return tmp; } //************************************************************************************************* @@ -661,10 +759,12 @@ inline BodyStorage::ConstIterator BodyStorage::release( ConstIterator pos ) * the element to be released. The time complexity is logarithmic unless reallocation occurs. */ -inline BodyStorage::Iterator BodyStorage::release( Iterator pos ) +inline std::unique_ptr<RigidBody> BodyStorage::release( iterator& pos ) { - release( (*pos)->getSystemID() ); - return pos; + auto diff = std::distance(bodies_.begin(), pos.get()); + auto tmp = release( pos->getSystemID() ); + pos = iterator(bodies_.begin() + diff); + return tmp; } //************************************************************************************************* @@ -681,9 +781,9 @@ inline BodyStorage::Iterator BodyStorage::release( Iterator pos ) * the element to be released. The time complexity is logarithmic unless reallocation occurs. */ -inline void BodyStorage::release( BodyID body ) +inline std::unique_ptr<RigidBody> BodyStorage::release( BodyID body ) { - release( body->getSystemID() ); + return release( body->getSystemID() ); } //************************************************************************************************* @@ -704,7 +804,7 @@ inline void BodyStorage::clear() { for (auto cb = removeCallbacks_.begin(); cb != removeCallbacks_.end(); ++cb) { - cb->second( *bodyIt ); + cb->second( bodyIt->get() ); } } @@ -766,7 +866,7 @@ inline void BodyStorage::clearRemoveCallbacks ( ) inline void BodyStorage::validate() { std::vector<bool> tmp(bodies_.size()); - std::map<id_t, SizeType>::iterator it = bodyIDs_.begin(); + std::map<id_t, size_type>::iterator it = bodyIDs_.begin(); while( it != bodyIDs_.end() ) { WALBERLA_ASSERT(tmp[it->second] == false, "Two system IDs point to the same storage index."); tmp[it->second] = true; diff --git a/src/pe/rigidbody/BoxFactory.cpp b/src/pe/rigidbody/BoxFactory.cpp index 6473eaa18e60f971b71d31614cdd3cb13b82889e..6f471ba55ee6fbf1a9838eef6b2da5ec91255958 100644 --- a/src/pe/rigidbody/BoxFactory.cpp +++ b/src/pe/rigidbody/BoxFactory.cpp @@ -26,6 +26,9 @@ #include "pe/rigidbody/BodyStorage.h" #include "pe/rigidbody/Box.h" +#include <core/logging/Logging.h> +#include <core/UniqueID.h> + namespace walberla { namespace pe { @@ -40,32 +43,31 @@ BoxID createBox( BodyStorage& globalStorage, BlockStorage& blocks, BlockDa if( lengths[0] <= real_t(0) || lengths[1] <= real_t(0) || lengths[2] <= real_t(0) ) throw std::invalid_argument( "Invalid side length" ); - BoxID box = NULL; + BoxID box = nullptr; if (global) { const id_t sid = UniqueID<RigidBody>::createGlobal(); WALBERLA_ASSERT_EQUAL(communicating, false); WALBERLA_ASSERT_EQUAL(infiniteMass, true); - box = new Box(sid, uid, gpos, Vec3(0,0,0), Quat(), lengths, material, global, false, true); - globalStorage.add(box); + BoxPtr bx = std::make_unique<Box>(sid, uid, gpos, Vec3(0,0,0), Quat(), lengths, material, global, false, true); + box = static_cast<BoxID>(&globalStorage.add(std::move(bx))); } else { - for (auto it = blocks.begin(); it != blocks.end(); ++it){ - IBlock* block = (&(*it)); - if (block->getAABB().contains(gpos)) + for (auto& block : blocks){ + if (block.getAABB().contains(gpos)) { const id_t sid( UniqueID<RigidBody>::create() ); - Storage* bs = block->getData<Storage>(storageID); - box = new Box(sid, uid, gpos, Vec3(0,0,0), Quat(), lengths, material, global, communicating, infiniteMass); - box->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block->getId().getID())); - (*bs)[0].add(box); + BodyStorage& bs = (*block.getData<Storage>(storageID))[0]; + BoxPtr bx = std::make_unique<Box>(sid, uid, gpos, Vec3(0,0,0), Quat(), lengths, material, global, communicating, infiniteMass); + bx->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID())); + box = static_cast<BoxID>(&bs.add(std::move(bx))); } } } - if (box != NULL) + if (box != nullptr) { // Logging the successful creation of the box WALBERLA_LOG_DETAIL( diff --git a/src/pe/rigidbody/CapsuleFactory.cpp b/src/pe/rigidbody/CapsuleFactory.cpp index 44b7839d11d8587d6415f9d0d52d3c885a4e6b23..325af9701f1c78bcf1497f2717fa586372d3e80b 100644 --- a/src/pe/rigidbody/CapsuleFactory.cpp +++ b/src/pe/rigidbody/CapsuleFactory.cpp @@ -26,6 +26,9 @@ #include "pe/rigidbody/BodyStorage.h" #include "pe/rigidbody/Capsule.h" +#include <core/logging/Logging.h> +#include <core/UniqueID.h> + namespace walberla { namespace pe { @@ -40,32 +43,31 @@ CapsuleID createCapsule( BodyStorage& globalStorage, BlockStorage& blocks, Blo WALBERLA_ASSERT_GREATER( radius, real_t(0), "Invalid capsule radius" ); WALBERLA_ASSERT_GREATER( length, real_t(0), "Invalid capsule length" ); - CapsuleID capsule = NULL; + CapsuleID capsule = nullptr; if (global) { const id_t sid = UniqueID<RigidBody>::createGlobal(); WALBERLA_ASSERT_EQUAL(communicating, false); WALBERLA_ASSERT_EQUAL(infiniteMass, true); - capsule = new Capsule(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, length, material, global, false, true); - globalStorage.add(capsule); + CapsulePtr cp = std::make_unique<Capsule>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, length, material, global, false, true); + capsule = static_cast<CapsuleID>(&globalStorage.add(std::move(cp))); } else { - for (auto it = blocks.begin(); it != blocks.end(); ++it){ - IBlock* block = (&(*it)); - if (block->getAABB().contains(gpos)) + for (auto& block : blocks){ + if (block.getAABB().contains(gpos)) { const id_t sid( UniqueID<RigidBody>::create() ); - Storage* bs = block->getData<Storage>(storageID); - capsule = new Capsule(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, length, material, global, communicating, infiniteMass); - capsule->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block->getId().getID())); - (*bs)[0].add(capsule); + BodyStorage& bs = (*block.getData<Storage>(storageID))[0]; + CapsulePtr cp = std::make_unique<Capsule>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, length, material, global, communicating, infiniteMass); + cp->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID())); + capsule = static_cast<CapsuleID>(&bs.add( std::move(cp) )); } } } - if (capsule != NULL) + if (capsule != nullptr) { // Logging the successful creation of the box WALBERLA_LOG_DETAIL( diff --git a/src/pe/rigidbody/CylindricalBoundary.cpp b/src/pe/rigidbody/CylindricalBoundary.cpp index 6b99c946384f11f2ecc5cd9f3d88a4e65956622d..66f639e49015a66ab41caf851690e678149c507b 100644 --- a/src/pe/rigidbody/CylindricalBoundary.cpp +++ b/src/pe/rigidbody/CylindricalBoundary.cpp @@ -56,7 +56,7 @@ namespace pe { CylindricalBoundary::CylindricalBoundary( id_t sid, id_t uid, const Vec3& gpos, const real_t radius, MaterialID material ) : GeomPrimitive( getStaticTypeID(), sid, uid, material ) // Initializing the base object - , radius_(radius) // Radius of the cylinder // Length of the capsule + , radius_(radius) // Radius of the cylinder { //boundaries are always considered locally and have infinite mass setGlobal( true ); @@ -66,11 +66,11 @@ CylindricalBoundary::CylindricalBoundary( id_t sid, id_t uid, const Vec3& gpos, // Checking the radius // Since the constructor is never directly called but only used in a small number - // of functions that already check the capsule arguments, only asserts are used here to + // of functions that already check the cylinder arguments, only asserts are used here to // double check the arguments. - WALBERLA_ASSERT_GREATER( radius, real_t(0), "Invalid capsule radius" ); + WALBERLA_ASSERT_GREATER( radius, real_t(0), "Invalid cylinder radius" ); - // Initializing the instantiated capsule + // Initializing the instantiated cylinder gpos_ = gpos; q_ = Quat(); // Setting the orientation R_ = q_.toRotationMatrix(); // Setting the rotation matrix diff --git a/src/pe/rigidbody/CylindricalBoundary.h b/src/pe/rigidbody/CylindricalBoundary.h index 4c095c1a20bae85959c756a856500ec7b4332b93..5d9b4c9d5da23922f0858500e065b25ca884a6f0 100644 --- a/src/pe/rigidbody/CylindricalBoundary.h +++ b/src/pe/rigidbody/CylindricalBoundary.h @@ -175,7 +175,7 @@ inline id_t CylindricalBoundary::getStaticTypeID() //================================================================================================= //************************************************************************************************* -/*!\name Capsule operators */ +/*!\name Cylinder operators */ //@{ std::ostream& operator<<( std::ostream& os, const CylindricalBoundary& cb ); std::ostream& operator<<( std::ostream& os, CylindricalBoundaryID cb ); diff --git a/src/pe/rigidbody/CylindricalBoundaryFactory.cpp b/src/pe/rigidbody/CylindricalBoundaryFactory.cpp index a82ea0c684ad7dbc7f60c2d02b99fb7eb6ded2f2..6cbf752cb9bb0c29f576e34c7ce336b2077ec4b1 100644 --- a/src/pe/rigidbody/CylindricalBoundaryFactory.cpp +++ b/src/pe/rigidbody/CylindricalBoundaryFactory.cpp @@ -24,7 +24,8 @@ #include "pe/rigidbody/BodyStorage.h" #include "pe/rigidbody/CylindricalBoundary.h" -#include "core/logging/Logging.h" +#include <core/logging/Logging.h> +#include <core/UniqueID.h> namespace walberla { namespace pe { @@ -37,9 +38,9 @@ CylindricalBoundaryID createCylindricalBoundary( BodyStorage& globalStorage, const id_t sid( UniqueID<RigidBody>::createGlobal() ); - CylindricalBoundaryID cb = new CylindricalBoundary( sid, uid, gpos, radius, material ); + CylindricalBoundaryPtr cbPtr = std::make_unique<CylindricalBoundary>( sid, uid, gpos, radius, material ); - globalStorage.add(cb); + CylindricalBoundaryID cb = static_cast<CylindricalBoundaryID>(&globalStorage.add(std::move(cbPtr))); // Logging the successful creation of the plane WALBERLA_LOG_DETAIL( "Created cylindrical boundary " << sid << "\n" << cb); diff --git a/src/pe/rigidbody/EllipsoidFactory.cpp b/src/pe/rigidbody/EllipsoidFactory.cpp index e848dd28527d9c763c55bab2b7e02467c82b05a3..8e8835b23d2507e053026d6cd081a95907436ddb 100644 --- a/src/pe/rigidbody/EllipsoidFactory.cpp +++ b/src/pe/rigidbody/EllipsoidFactory.cpp @@ -25,40 +25,42 @@ #include "pe/rigidbody/BodyStorage.h" #include "pe/rigidbody/Ellipsoid.h" +#include <core/logging/Logging.h> +#include <core/UniqueID.h> + namespace walberla { namespace pe { EllipsoidID createEllipsoid( BodyStorage& globalStorage, BlockStorage& blocks, BlockDataID storageID, - id_t uid, const Vec3& gpos, const Vec3& semiAxes, - MaterialID material, - bool global, bool communicating, bool infiniteMass ) + id_t uid, const Vec3& gpos, const Vec3& semiAxes, + MaterialID material, + bool global, bool communicating, bool infiniteMass ) { WALBERLA_ASSERT_UNEQUAL( Ellipsoid::getStaticTypeID(), std::numeric_limits<id_t>::max(), "Ellipsoid TypeID not initalized!"); // Checking the semiAxes if( semiAxes[0] <= real_c(0) || semiAxes[1] <= real_c(0) || semiAxes[2] <= real_c(0) ) throw std::invalid_argument( "Invalid Ellipsoid semi-axes" ); - EllipsoidID ellipsoid = NULL; + EllipsoidID ellipsoid = nullptr; if (global) { const id_t sid = UniqueID<RigidBody>::createGlobal(); WALBERLA_ASSERT_EQUAL(communicating, false); WALBERLA_ASSERT_EQUAL(infiniteMass, true); - ellipsoid = new Ellipsoid(sid, uid, gpos, Vec3(0,0,0), Quat(), semiAxes, material, global, false, true); - globalStorage.add(ellipsoid); + EllipsoidPtr el = std::make_unique<Ellipsoid>(sid, uid, gpos, Vec3(0,0,0), Quat(), semiAxes, material, global, false, true); + ellipsoid = static_cast<EllipsoidID>(&globalStorage.add(std::move(el))); } else { - for (auto it = blocks.begin(); it != blocks.end(); ++it){ - IBlock* block = (&(*it)); - if (block->getAABB().contains(gpos)) + for (auto& block : blocks){ + if (block.getAABB().contains(gpos)) { const id_t sid( UniqueID<RigidBody>::create() ); - Storage* bs = block->getData<Storage>(storageID); - ellipsoid = new Ellipsoid(sid, uid, gpos, Vec3(0,0,0), Quat(), semiAxes, material, global, communicating, infiniteMass); - ellipsoid->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block->getId().getID())); - (*bs)[0].add(ellipsoid); + BodyStorage& bs = (*block.getData<Storage>(storageID))[0]; + EllipsoidPtr el = std::make_unique<Ellipsoid>(sid, uid, gpos, Vec3(0,0,0), Quat(), semiAxes, material, global, communicating, infiniteMass); + el->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID())); + ellipsoid = static_cast<EllipsoidID>(&bs.add(std::move(el))); } } } @@ -67,12 +69,12 @@ EllipsoidID createEllipsoid( BodyStorage& globalStorage, BlockStorage& blocks, B { // Logging the successful creation of the Ellipsoid WALBERLA_LOG_DETAIL( - "Created Ellipsoid " << ellipsoid->getSystemID() << "\n" - << " User-ID = " << uid << "\n" - << " Global position = " << gpos << "\n" - << " Semi-axes = " << semiAxes << "\n" - << " LinVel = " << ellipsoid->getLinearVel() << "\n" - << " Material = " << Material::getName( material ) + "Created Ellipsoid " << ellipsoid->getSystemID() << "\n" + << " User-ID = " << uid << "\n" + << " Global position = " << gpos << "\n" + << " Semi-axes = " << semiAxes << "\n" + << " LinVel = " << ellipsoid->getLinearVel() << "\n" + << " Material = " << Material::getName( material ) ); } diff --git a/src/pe/rigidbody/Node.h b/src/pe/rigidbody/Node.h deleted file mode 100644 index 584d44e4f5bb66ce8c2d55d7891992178776160e..0000000000000000000000000000000000000000 --- a/src/pe/rigidbody/Node.h +++ /dev/null @@ -1,137 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file Node.h -//! \author Klaus Iglberger -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -// -//====================================================================================================================== - -#pragma once - - -//************************************************************************************************* -// Includes -//************************************************************************************************* - -#include <pe/Types.h> -#include <core/DataTypes.h> - -namespace walberla { -namespace pe { - -//================================================================================================= -// -// SPECIALIZATION FOR THE UNION FIND ALGORITHM -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Node for the 'Union Find' algorithm. - * - * This specialization of the BodyTrait class template adapts rigid bodies to the 'Union Find' - * batch generation algorithm. In this algorithm, rigid bodies act as nodes in a graph and - * contacts between the rigid bodies act as edges. - */ -class Node -{ -public: - - //**Constructor********************************************************************************* - /*!\name Constructor */ - //@{ - explicit inline Node(); - //@} - //********************************************************************************************** - - //**Node functions****************************************************************************** - /*!\name Node functions */ - //@{ - inline ConstNodeID getRoot() const; - inline void resetNode() const; - //@} - //********************************************************************************************** - -public: - //**Member variables**************************************************************************** - /*!\name Member variables */ - //@{ - mutable ConstNodeID root_; //!< The root of the contact graph containing the rigid body. - mutable size_t rank_; //!< The current rank of the rigid body in the contact graph. - mutable size_t batch_; //!< Index of the batch containing all contacts in the contact graph. - //@} - //********************************************************************************************** -}; -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Default constructor for the BodyTrait<UnionFind> specialization. - */ -inline Node::Node() - : rank_ ( 0 ) - , batch_( 0 ) -{ - root_ = this ; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Calculating the current root of the contact graph. - * - * \return The current root of the contact graph. - * - * This function returns the current root of the contact graph and compresses the graph for - * a fast access to the root node. - */ -inline ConstNodeID Node::getRoot() const -{ - ConstNodeID root( this ); - - // Traverse the contact graph to find the root node - while( root->root_ != root ) { - root = root->root_; - } - - // Retraverse the graph for graph compression - ConstNodeID tmp( this ); - while( tmp->root_ != tmp ) { - ConstNodeID last = tmp; - tmp = tmp->root_; - last->root_ = root; - } - - return root; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Resetting the data members of the node. - * - * \return void - */ -inline void Node::resetNode() const -{ - root_ = this; - rank_ = 0; - batch_ = 0; -} -//************************************************************************************************* - -} // namespace pe - -} // namespace walberla diff --git a/src/pe/rigidbody/PlaneFactory.cpp b/src/pe/rigidbody/PlaneFactory.cpp index 2f780a12a1d1377fcf72b283d082e0e3a1320884..650054ee07b68655d53d5e959122d35ed66ea2ce 100644 --- a/src/pe/rigidbody/PlaneFactory.cpp +++ b/src/pe/rigidbody/PlaneFactory.cpp @@ -26,7 +26,8 @@ #include "pe/rigidbody/BodyStorage.h" #include "pe/rigidbody/Plane.h" -#include "core/logging/Logging.h" +#include <core/logging/Logging.h> +#include <core/UniqueID.h> namespace walberla { namespace pe { @@ -44,9 +45,8 @@ PlaneID createPlane( BodyStorage& globalStorage, id_t uid, Vec3 normal, const Ve const id_t sid( UniqueID<RigidBody>::createGlobal() ); - PlaneID plane = new Plane( sid, uid, gpos, normal, normal*gpos, material ); - - globalStorage.add(plane); + PlanePtr pl = std::make_unique<Plane>( sid, uid, gpos, normal, normal*gpos, material ); + PlaneID plane = static_cast<PlaneID>(&globalStorage.add(std::move(pl))); // Logging the successful creation of the plane WALBERLA_LOG_DETAIL( "Created plane " << sid << "\n" diff --git a/src/pe/rigidbody/RigidBody.cpp b/src/pe/rigidbody/RigidBody.cpp index 45d40109e31a29020a55517e8c28b1b5fecddf2f..f23bde4e08d0e5c320a89a356cfdb3cdc2988e18 100644 --- a/src/pe/rigidbody/RigidBody.cpp +++ b/src/pe/rigidbody/RigidBody.cpp @@ -33,8 +33,7 @@ namespace pe{ * \param uid The user-specific ID of the rigid body. */ RigidBody::RigidBody( id_t const typeID, id_t sid, id_t uid ) - : Node() - , awake_( true ) // Sleep mode flag + : awake_( true ) // Sleep mode flag , mass_( 0 ) // Total mass of the rigid body , invMass_( 0 ) // Inverse total mass of the rigid body , motion_(sleepThreshold) // The current motion of the rigid body @@ -57,7 +56,6 @@ RigidBody::RigidBody( id_t const typeID, id_t sid, id_t uid ) , toBeDeleted_(false) // deletion flag , sid_ (sid) // System-specific body index , uid_ (uid) // User-specific body ID - , contacts_() // Vector of the currently attached contacts , typeID_(typeID) // geometry type { sb_ = this; // The superordinate rigid body diff --git a/src/pe/rigidbody/RigidBody.h b/src/pe/rigidbody/RigidBody.h index 119616748a90f49f94333ad14cf0d5335b35650e..fdebc3ff61424cbbdcc213d45bb2d473b6d07014 100644 --- a/src/pe/rigidbody/RigidBody.h +++ b/src/pe/rigidbody/RigidBody.h @@ -28,16 +28,12 @@ #include "core/math/Matrix3.h" #include "core/math/Quaternion.h" #include "core/math/Vector3.h" -#include <pe/rigidbody/Node.h> #include "core/NonCopyable.h" #include "core/DataTypes.h" -#include "core/ptrvector/PtrVector.h" -#include "core/ptrvector/policies/NoDelete.h" #include "core/debug/Debug.h" #include "core/logging/Logging.h" #include "core/math/AABB.h" -#include "pe/attachable/Attachable.h" #include "pe/rigidbody/MPIRigidBodyTrait.h" namespace walberla{ @@ -49,8 +45,7 @@ class Union; /** * \ingroup pe */ -class RigidBody : public Node - , public ccd::HashGridsBodyTrait +class RigidBody : public ccd::HashGridsBodyTrait , public cr::HCSITSBodyTrait , private NonCopyable { @@ -58,21 +53,6 @@ private: template <typename BodyTypeTuple> friend class Union; - //**Type definitions**************************************************************************** - typedef PtrVector<RigidBody,NoDelete> Bodies; //!< Vector for superordinate bodies containing this rigid body. - typedef PtrVector<Contact,NoDelete> Contacts; //!< Vector for attached contacts. - typedef PtrVector<Attachable,NoDelete> Attachables; //!< Vector for attachables. - //********************************************************************************************** - -public: - //**Type definitions**************************************************************************** - typedef Contacts::Iterator ContactIterator; //!< Iterator over the currently attached contacts. - typedef Contacts::ConstIterator ConstContactIterator; //!< ConstIterator over the currently attached contacts. - typedef Attachables::Iterator AttachableIterator; //!< Iterator over the currently attached attachables. - typedef Attachables::ConstIterator ConstAttachableIterator; //!< ConstIterator over the currently attached attachables. - typedef Bodies::Iterator AttachedBodyIterator; //!< Iterator over the currently attached rigid bodies. - typedef Bodies::ConstIterator ConstAttachedBodyIterator; //!< ConstIterator over the currently attached rigid bodies. - //********************************************************************************************** protected: //**Constructor********************************************************************************* /*!\name Constructor */ @@ -275,38 +255,6 @@ public: //@} //********************************************************************************************** - //**Contact functions*************************************************************************** - /*!\name Contact functions */ - //@{ - inline void registerContact( ContactID contact ); - inline bool hasContacts () const; - inline void clearContacts(); - inline size_t countContacts() const; - inline ContactIterator beginContacts(); - inline ConstContactIterator beginContacts() const; - inline ContactIterator endContacts (); - inline ConstContactIterator endContacts () const; - //@} - //********************************************************************************************** - - //**Attachable functions************************************************************************ - /*!\name Attachable functions */ - //@{ - void registerAttachable ( AttachableID attachable ); - void deregisterAttachable( AttachableID attachable ); - inline bool isAttached () const; - inline size_t countAttachables () const; - inline AttachableIterator beginAttachables (); - inline ConstAttachableIterator beginAttachables () const; - inline AttachableIterator endAttachables (); - inline ConstAttachableIterator endAttachables () const; - inline AttachedBodyIterator beginAttachedBodies (); - inline ConstAttachedBodyIterator beginAttachedBodies () const; - inline AttachedBodyIterator endAttachedBodies (); - inline ConstAttachedBodyIterator endAttachedBodies () const; - //@} - //********************************************************************************************** - //**MPI functions******************************************************************************* /*!\name MPI functions */ //@{ @@ -460,9 +408,6 @@ protected: bool toBeDeleted_; //!< This flag marks the body for deletion during the next synchronization (only works on local bodies) id_t sid_; //!< The unique system-specific body ID. id_t uid_; //!< The user-specific body ID. - Contacts contacts_; //!< Vector for the currently attached contacts. - Attachables attachables_; //!< Vector for the currently attached attachables. - Bodies attachedBodies_; //!< Vector for the currently attached rigid bodies. //@} //********************************************************************************************** @@ -1170,7 +1115,11 @@ const Vec3 RigidBody::accFromWF( real_t px, real_t py, real_t pz ) const } //************************************************************************************************* -inline id_t RigidBody::getTypeID() const{ +inline id_t RigidBody::getTypeID() const +{ + WALBERLA_ASSERT_LESS( typeID_, std::numeric_limits<id_t>::max(), "You are requesting the type " \ + " id of a body, but the static type id for the body has not yet been " \ + " initialized! Call SetBodyTypeIDs<BodyTypeTuple>::execute to initialize!" ); return typeID_; } @@ -1939,240 +1888,6 @@ inline void RigidBody::signalFixation() -//================================================================================================= -// -// CONTACT FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Registering a single attached contact with the rigid body. - * - * \param contact The contact to be registered with the rigid body. - * \return void - */ -inline void RigidBody::registerContact( ContactID contact ) -{ - WALBERLA_ASSERT( !hasSuperBody(), "Invalid contact on subordinate body detected" ); - contacts_.pushBack( contact ); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Clears all contacts registered with the rigid body. - * - * \return void - */ -inline void RigidBody::clearContacts() -{ - contacts_.clear(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns whether any contacts are registered with the rigid body. - * - * \return \a true if at least one contact is registered with the rigid body, \a false if not. - */ -inline bool RigidBody::hasContacts() const -{ - return !contacts_.isEmpty(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns the number of currently registered contacts. - * - * \return The number of registered contacts. - */ -inline size_t RigidBody::countContacts() const -{ - return contacts_.size(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator to the first attached contact. - * - * \return Iterator to the first attached contact. - */ -inline RigidBody::ContactIterator RigidBody::beginContacts() -{ - return contacts_.begin(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator to the first attached contact. - * - * \return Iterator to the first attached contact. - */ -inline RigidBody::ConstContactIterator RigidBody::beginContacts() const -{ - return contacts_.begin(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator just past the last attached contact. - * - * \return Iterator just past the last attached contact. - */ -inline RigidBody::ContactIterator RigidBody::endContacts() -{ - return contacts_.end(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator just past the last attached contact. - * - * \return Iterator just past the last attached contact. - */ -inline RigidBody::ConstContactIterator RigidBody::endContacts() const -{ - return contacts_.end(); -} -//************************************************************************************************* - - - - -//================================================================================================= -// -// ATTACHABLE FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Returns whether any attachable is registered with the rigid body. - * - * \return \a true in case at least one attachable is registered with the rigid body, \a false otherwise. - */ -inline bool RigidBody::isAttached() const -{ - return !attachables_.isEmpty(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns the number of currently registered attachables. - * - * \return The number of registered attachables. - */ -inline size_t RigidBody::countAttachables() const -{ - return attachables_.size(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator to the first registered attachable. - * - * \return Iterator to the first registered attachable. - */ -inline RigidBody::AttachableIterator RigidBody::beginAttachables() -{ - return attachables_.begin(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator to the first registered attachable. - * - * \return Iterator to the first registered attachable. - */ -inline RigidBody::ConstAttachableIterator RigidBody::beginAttachables() const -{ - return attachables_.begin(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator just past the last registered attachable. - * - * \return Iterator just past the last registered attachable. - */ -inline RigidBody::AttachableIterator RigidBody::endAttachables() -{ - return attachables_.end(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator just past the last registered attachable. - * - * \return Iterator just past the last registered attachable. - */ -inline RigidBody::ConstAttachableIterator RigidBody::endAttachables() const -{ - return attachables_.end(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator to the first attached rigid body. - * - * \return Iterator to the first attached rigid body. - */ -inline RigidBody::AttachedBodyIterator RigidBody::beginAttachedBodies() -{ - return attachedBodies_.begin(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator to the first attached rigid body. - * - * \return Iterator to the first attached rigid body. - */ -inline RigidBody::ConstAttachedBodyIterator RigidBody::beginAttachedBodies() const -{ - return attachedBodies_.begin(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator just past the last attached rigid body. - * - * \return Iterator just past the last attached rigid body. - */ -inline RigidBody::AttachedBodyIterator RigidBody::endAttachedBodies() -{ - return attachedBodies_.end(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns an iterator just past the last attached rigid body. - * - * \return Iterator just past the last attached rigid body. - */ -inline RigidBody::ConstAttachedBodyIterator RigidBody::endAttachedBodies() const -{ - return attachedBodies_.end(); -} -//************************************************************************************************* - - - - //================================================================================================= // // MPI FUNCTIONS @@ -3343,73 +3058,6 @@ inline void RigidBody::update( const Quat& dq ) -//================================================================================================= -// -// ATTACHABLE FUNCTIONS -// -//================================================================================================= - -//************************************************************************************************* -/*!\brief Registering a single attachable with the rigid body. - * - * \param attachable The attachable to be registered with the rigid body. - * \return void - * - * This function must NOT be called explicitly, but is reserved for internal use only! - * Attachables are automatically registered during their construction process. - */ -inline void RigidBody::registerAttachable( AttachableID attachable ) -{ - // Registering the attachable - attachables_.pushBack( attachable ); - - // Registering all newly attached rigid bodies - const Attachable::Iterator end( attachable->end() ); - for( Attachable::Iterator body=attachable->begin(); body!=end; ++body ) { - const AttachedBodyIterator bbegin( attachedBodies_.begin() ); - const AttachedBodyIterator bend ( attachedBodies_.end() ); - if( *body != this && std::find( bbegin, bend, *body ) == bend ) - attachedBodies_.pushBack( *body ); - } -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Deregistering a single attachable from the rigid body. - * - * \param attachable The attachable to be deregistered from the rigid body. - * \return void - * - * This function must NOT be called explicitly, but is reserved for internal use only! - * Attachables are automatically deregistered during their destruction process. - */ -inline void RigidBody::deregisterAttachable( AttachableID attachable ) -{ - // Deregistering the attachable - Attachables::Iterator pos( std::find( attachables_.begin(), attachables_.end(), attachable ) ); - WALBERLA_ASSERT( pos != attachables_.end(), "Attachable is not registered" ); - attachables_.erase( pos ); - - // Deregistering all attached rigid bodies - attachedBodies_.clear(); - - // Recreating the vector of attached rigid bodies - for( Attachables::Iterator it=attachables_.begin(); it!=attachables_.end(); ++it ) { - const Attachable::Iterator end( it->end() ); - for( Attachable::Iterator body=it->begin(); body!=end; ++body ) { - const AttachedBodyIterator bbegin( attachedBodies_.begin() ); - const AttachedBodyIterator bend ( attachedBodies_.end() ); - if( *body != this && std::find( bbegin, bend, *body ) == bend ) - attachedBodies_.pushBack( *body ); - } - } -} -//************************************************************************************************* - - - - //================================================================================================= // // SIMULATION FUNCTIONS diff --git a/src/pe/rigidbody/RigidBodyCastIterator.h b/src/pe/rigidbody/RigidBodyCastIterator.h new file mode 100644 index 0000000000000000000000000000000000000000..7241baa63ce3b6eac5bafb20be5571016f992526 --- /dev/null +++ b/src/pe/rigidbody/RigidBodyCastIterator.h @@ -0,0 +1,315 @@ +//====================================================================================================================== +// +// This file is part of waLBerla. waLBerla is free software: you can +// redistribute it and/or modify it under the terms of the GNU General Public +// License as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// waLBerla is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. +// +//! \file RigidBodyCastIterator.h +//! \author Klaus Iglberger +//! \author Sebastian Eibl <sebastian.eibl@fau.de> +// +//====================================================================================================================== + +#pragma once + +#include "RigidBody.h" + +#include <memory> +#include <type_traits> +#include <vector> + +namespace walberla { +namespace pe { + +//************************************************************************************************* +/*!\brief Dynamic cast iterator for polymorphic pointer vectors. + * + * The RigidBodyCastIterator is a forward iterator which only selects elements of type C. + * Dereferencing this iterator will implicitly cast to C. + */ +template <typename C> +class RigidBodyCastIterator +{ + static_assert(std::is_base_of<RigidBody, C>::value && !std::is_base_of<C, RigidBody>::value, + "C has to be strictly derived from RigidBody"); + + template <typename C2> + friend inline bool operator==( const RigidBodyCastIterator<C2>& lhs, const RigidBodyCastIterator<C2>& rhs ); + template <typename C2> + friend inline bool operator!=( const RigidBodyCastIterator<C2>& lhs, const RigidBodyCastIterator<C2>& rhs ); +public: + using ContainerType = std::vector< std::unique_ptr<RigidBody> >; + //**Type definitions**************************************************************************** + // STL iterator requirements + using iterator_category = std::forward_iterator_tag; + using value_type = C; + using pointer = C*; + using reference = C&; + using difference_type = std::ptrdiff_t; + //********************************************************************************************** + + //**Constructors******************************************************************************** + /*!\name Constructors */ + //@{ + inline RigidBodyCastIterator() {} + explicit inline RigidBodyCastIterator( const typename ContainerType::iterator& begin, const typename ContainerType::iterator& end ); + + RigidBodyCastIterator( const RigidBodyCastIterator<C>& it) = default; + RigidBodyCastIterator( RigidBodyCastIterator<C>&& it) = default; + + RigidBodyCastIterator& operator=(const RigidBodyCastIterator<C>& it) = default; + RigidBodyCastIterator& operator=(RigidBodyCastIterator<C>&& it) = default; + + //**Operators*********************************************************************************** + /*!\name Operators */ + //@{ + inline RigidBodyCastIterator<C>& operator++(); + inline RigidBodyCastIterator<C> operator++( int ) {RigidBodyCastIterator<C> tmp(*this); ++(*this); return tmp;} + //@} + //********************************************************************************************** + + //**Access operators**************************************************************************** + /*!\name Access operators */ + //@{ + inline reference operator*() {return static_cast<reference>( *(cur_->get()) );} + inline pointer operator->() {return static_cast<pointer>( cur_->get() );} + //@} + //********************************************************************************************** + + //**Utility functions*************************************************************************** + /*!\name Utility functions */ + //@{ + inline pointer getBodyID() {return static_cast<pointer>(cur_->get());} + //@} + //********************************************************************************************** + +private: + //**Member variables**************************************************************************** + /*!\name Member variables */ + //@{ + typename ContainerType::iterator cur_; //!< Pointer to the current memory location. + typename ContainerType::iterator end_; //!< Pointer to the element one past the last element in the element range. + //@} + //********************************************************************************************** +}; +//************************************************************************************************* + + +//************************************************************************************************* +/*!\brief Standard constructor for CastIterator. + * + * \param begin The beginning of the element range. + * \param end The end of the element range. + */ +template< typename C > // Cast type +inline RigidBodyCastIterator<C>::RigidBodyCastIterator( const typename ContainerType::iterator& begin, + const typename ContainerType::iterator& end ) + : cur_(begin) // Pointer to the current memory location + , end_(end) // Pointer to the element one past the last element in the element range +{ + cur_ = std::find_if(cur_, end_, [](const ContainerType::iterator::value_type& p) {return p->getTypeID() == C::getStaticTypeID();}); +} +//************************************************************************************************* + +//************************************************************************************************* +/*!\brief Pre-increment operator. + * + * \return Reference to the incremented cast iterator. + */ +template< typename C > +inline RigidBodyCastIterator<C>& RigidBodyCastIterator<C>::operator++() +{ + cur_ = std::find_if(++cur_, end_, [](const ContainerType::iterator::value_type& p) {return p->getTypeID() == C::getStaticTypeID();}); + + return *this; +} +//************************************************************************************************* + + +//********************************************************************************************** +/*!\brief Equality comparison between two CastIterator objects. +// +// \param lhs The left hand side cast iterator. +// \param rhs The right hand side cast iterator. +// \return \a true if the iterators point to the same element, \a false if not. +*/ +template< typename C > +inline bool operator==( const RigidBodyCastIterator<C>& lhs, const RigidBodyCastIterator<C>& rhs ) +{ + return lhs.cur_ == rhs.cur_; +} +//********************************************************************************************** + +//********************************************************************************************** +/*!\brief Inequality comparison between two CastIterator objects. +// +// \param lhs The left hand side cast iterator. +// \param rhs The right hand side cast iterator. +// \return \a true if the iterators don't point to the same element, \a false if they do. +*/ +template< typename C > +inline bool operator!=( const RigidBodyCastIterator<C>& lhs, const RigidBodyCastIterator<C>& rhs ) +{ + return !operator==(lhs, rhs); +} +//********************************************************************************************** + + + + + + + + + + + + + + + + + + + + + +template <typename C> +class ConstRigidBodyCastIterator +{ + static_assert(std::is_base_of<RigidBody, C>::value && !std::is_base_of<C, RigidBody>::value, + "C has to be strictly derived from RigidBody"); + + template <typename C2> + friend bool operator==( const ConstRigidBodyCastIterator<C2>& lhs, const ConstRigidBodyCastIterator<C2>& rhs ); + template <typename C2> + friend bool operator!=( const ConstRigidBodyCastIterator<C2>& lhs, const ConstRigidBodyCastIterator<C2>& rhs ); +public: + using ContainerType = std::vector< std::unique_ptr<RigidBody> >; + //**Type definitions**************************************************************************** + // STL iterator requirements + using iterator_category = std::forward_iterator_tag; + using value_type = C const; + using pointer = C const *; + using reference = C const &; + using difference_type = std::ptrdiff_t; + //********************************************************************************************** + + //**Constructors******************************************************************************** + /*!\name Constructors */ + //@{ + inline ConstRigidBodyCastIterator() {} + explicit inline ConstRigidBodyCastIterator( const typename ContainerType::const_iterator& begin, + const typename ContainerType::const_iterator& end ); + + ConstRigidBodyCastIterator( const ConstRigidBodyCastIterator<C>& it) = default; + ConstRigidBodyCastIterator( ConstRigidBodyCastIterator<C>&& it) = default; + + ConstRigidBodyCastIterator& operator=(const ConstRigidBodyCastIterator<C>& it) = default; + ConstRigidBodyCastIterator& operator=(ConstRigidBodyCastIterator<C>&& it) = default; + + //**Operators*********************************************************************************** + /*!\name Operators */ + //@{ + inline ConstRigidBodyCastIterator<C>& operator++(); + inline ConstRigidBodyCastIterator<C> operator++( int ) {ConstRigidBodyCastIterator<C> tmp(*this); ++(*this); return tmp;} + //@} + //********************************************************************************************** + + //**Access operators**************************************************************************** + /*!\name Access operators */ + //@{ + inline reference operator*() {return static_cast<reference>( *(cur_->get()) );} + inline pointer operator->() {return static_cast<pointer>( cur_->get() );} + //@} + //********************************************************************************************** + + //**Utility functions*************************************************************************** + /*!\name Utility functions */ + //@{ + inline pointer getBodyID() {return static_cast<pointer>(cur_->get());} + //@} + //********************************************************************************************** + +private: + //**Member variables**************************************************************************** + /*!\name Member variables */ + //@{ + typename ContainerType::const_iterator cur_; //!< Pointer to the current memory location. + typename ContainerType::const_iterator end_; //!< Pointer to the element one past the last element in the element range. + //@} + //********************************************************************************************** +}; +//************************************************************************************************* + + +//************************************************************************************************* +/*!\brief Standard constructor for CastIterator. + * + * \param begin The beginning of the element range. + * \param end The end of the element range. + */ +template< typename C > // Cast type +inline ConstRigidBodyCastIterator<C>::ConstRigidBodyCastIterator( const typename ContainerType::const_iterator& begin, + const typename ContainerType::const_iterator& end ) + : cur_(begin) // Pointer to the current memory location + , end_(end) // Pointer to the element one past the last element in the element range +{ + cur_ = std::find_if(cur_, end_, [](const ContainerType::const_iterator::value_type& p) {return p->getTypeID() == C::getStaticTypeID();}); +} +//************************************************************************************************* + +//************************************************************************************************* +/*!\brief Pre-increment operator. + * + * \return Reference to the incremented cast iterator. + */ +template< typename C > +inline ConstRigidBodyCastIterator<C>& ConstRigidBodyCastIterator<C>::operator++() +{ + cur_ = std::find_if(++cur_, end_, [](const ContainerType::const_iterator::value_type& p) {return p->getTypeID() == C::getStaticTypeID();}); + + return *this; +} +//************************************************************************************************* + + +//********************************************************************************************** +/*!\brief Equality comparison between two CastIterator objects. +// +// \param lhs The left hand side cast iterator. +// \param rhs The right hand side cast iterator. +// \return \a true if the iterators point to the same element, \a false if not. +*/ +template< typename C > +inline bool operator==( const ConstRigidBodyCastIterator<C>& lhs, const ConstRigidBodyCastIterator<C>& rhs ) +{ + return lhs.cur_ == rhs.cur_; +} +//********************************************************************************************** + +//********************************************************************************************** +/*!\brief Inequality comparison between two CastIterator objects. +// +// \param lhs The left hand side cast iterator. +// \param rhs The right hand side cast iterator. +// \return \a true if the iterators don't point to the same element, \a false if they do. +*/ +template< typename C > +inline bool operator!=( const ConstRigidBodyCastIterator<C>& lhs, const ConstRigidBodyCastIterator<C>& rhs ) +{ + return !operator==(lhs, rhs); +} +//********************************************************************************************** + +} // namespace pe +} // namespace walberla diff --git a/src/pe/rigidbody/RigidBodyIterator.h b/src/pe/rigidbody/RigidBodyIterator.h new file mode 100644 index 0000000000000000000000000000000000000000..8e2be67d2f299dde26ebb313b4a17e4c22642301 --- /dev/null +++ b/src/pe/rigidbody/RigidBodyIterator.h @@ -0,0 +1,367 @@ +//====================================================================================================================== +// +// This file is part of waLBerla. waLBerla is free software: you can +// redistribute it and/or modify it under the terms of the GNU General Public +// License as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// waLBerla is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. +// +//! \file RigidBodyIterator.h +//! \author Klaus Iglberger +//! \author Sebastian Eibl <sebastian.eibl@fau.de> +// +//====================================================================================================================== + +#pragma once + +#include "RigidBody.h" + +#include <memory> +#include <type_traits> +#include <vector> + +namespace walberla { +namespace pe { + +//************************************************************************************************* +/*!\brief Implementation of an iterator for pointer vectors. + * + * This iterator implementation will automatically dereference twice at dereference calls! + * Therefore the return types are not unique_ptrs but RigidBodys. + */ +class RigidBodyIterator +{ + friend inline bool operator==( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs ); + friend inline bool operator!=( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs ); + friend inline bool operator>( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs ); + friend inline bool operator<( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs ); + friend inline bool operator>=( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs ); + friend inline bool operator<=( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs ); +public: + using ContainerType = std::vector< std::unique_ptr<RigidBody> >; + //**Type definitions**************************************************************************** + // STL iterator requirements + using iterator_category = std::random_access_iterator_tag; + using value_type = RigidBody; + using pointer = RigidBody*; + using reference = RigidBody&; + using difference_type = std::ptrdiff_t; + //********************************************************************************************** + + //**Constructors******************************************************************************** + /*!\name Constructors */ + //@{ + inline RigidBodyIterator() {} + explicit inline RigidBodyIterator( const typename ContainerType::iterator& it ) : it_(it) {} + + RigidBodyIterator( const RigidBodyIterator& it) = default; + RigidBodyIterator( RigidBodyIterator&& it) = default; + + RigidBodyIterator& operator=(const RigidBodyIterator& it) = default; + RigidBodyIterator& operator=(RigidBodyIterator&& it) = default; + + //**Operators*********************************************************************************** + /*!\name Operators */ + //@{ + inline RigidBodyIterator& operator++() {++it_; return *this;} + inline RigidBodyIterator operator++( int ) {RigidBodyIterator tmp(*this); ++(*this); return tmp;} + inline RigidBodyIterator& operator--() {--it_; return *this;} + inline RigidBodyIterator operator--( int ) {RigidBodyIterator tmp(*this); --(*this); return tmp;} + inline RigidBodyIterator& operator+=( difference_type n ) {it_ += n; return *this;} + inline RigidBodyIterator operator+ ( difference_type n ) const {return RigidBodyIterator( it_ + n );} + inline RigidBodyIterator& operator-=( difference_type n ) {it_ -= n; return *this;} + inline RigidBodyIterator operator- ( difference_type n ) const {return RigidBodyIterator( it_ - n );} + inline difference_type operator- ( const RigidBodyIterator& it ) const {return it_ - it.it_;} + //@} + //********************************************************************************************** + + //**Access operators**************************************************************************** + /*!\name Access operators */ + //@{ + inline reference operator[]( difference_type n ) const {return *it_[n];} + inline reference operator*() const {return **it_;} + inline pointer operator->() const {return it_->get();} + //@} + //********************************************************************************************** + + //**Utility functions*************************************************************************** + /*!\name Utility functions */ + //@{ + inline pointer getBodyID() {return it_->get();} + inline ContainerType::iterator get() const {return it_;} + //@} + //********************************************************************************************** + +private: + //**Member variables**************************************************************************** + /*!\name Member variables */ + //@{ + typename ContainerType::iterator it_; //!< wrapped iterator + //@} + //********************************************************************************************** +}; +//************************************************************************************************* + + +//************************************************************************************************* +/*!\brief Equality comparison between two PtrIterator objects. + * + * \param lhs The left-hand side pointer iterator. + * \param rhs The right-hand side pointer iterator. + * \return \a true if the iterators point to the same element, \a false if not. + */ +inline bool operator==( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs ) +{ + return lhs.it_ == rhs.it_; +} +//************************************************************************************************* + + +//************************************************************************************************* +/*!\brief Inequality comparison between two PtrIterator objects. + * + * \param lhs The left-hand side pointer iterator. + * \param rhs The right-hand side pointer iterator. + * \return \a true if the iterators don't point to the same element, \a false if they do. + */ +inline bool operator!=( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs ) +{ + return !operator==(lhs, rhs); +} +//************************************************************************************************* + + +//************************************************************************************************* +/*!\brief Less-than comparison between two PtrIterator objects. + * + * \param lhs The left-hand side pointer iterator. + * \param rhs The right-hand side pointer iterator. + * \return \a true if the left-hand side iterator points to a lower element, \a false if not. + */ +inline bool operator<( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs ) +{ + return lhs.it_ < rhs.it_; +} +//************************************************************************************************* + + +//************************************************************************************************* +/*!\brief Greater-than comparison between two PtrIterator objects. + * + * \param lhs The left-hand side pointer iterator. + * \param rhs The right-hand side pointer iterator. + * \return \a true if the left-hand side iterator points to a higher element, \a false if not. + */ +inline bool operator>( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs ) +{ + return lhs.it_ > rhs.it_; +} +//************************************************************************************************* + + +//************************************************************************************************* +/*!\brief Less-or-equal-than comparison between two PtrIterator objects. + * + * \param lhs The left-hand side pointer iterator. + * \param rhs The right-hand side pointer iterator. + * \return \a true if the left-hand side iterator points to a lower or the same element, \a false if not. + */ +inline bool operator<=( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs ) +{ + return lhs.it_ <= rhs.it_; +} +//************************************************************************************************* + + +//************************************************************************************************* +/*!\brief Greater-or-equal-than comparison between two PtrIterator objects. + * + * \param lhs The left-hand side pointer iterator. + * \param rhs The right-hand side pointer iterator. + * \return \a true if the left-hand side iterator points to a higher or the same element, \a false if not. + */ +inline bool operator>=( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs ) +{ + return lhs.it_ >= rhs.it_; +} +//************************************************************************************************* + + + + + + + + + + + + +class ConstRigidBodyIterator +{ + friend inline bool operator==( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs ); + friend inline bool operator!=( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs ); + friend inline bool operator>( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs ); + friend inline bool operator<( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs ); + friend inline bool operator>=( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs ); + friend inline bool operator<=( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs ); +public: + using ContainerType = std::vector< std::unique_ptr<RigidBody> >; + //**Type definitions**************************************************************************** + // STL iterator requirements + using iterator_category = std::random_access_iterator_tag; + using value_type = RigidBody const; + using pointer = RigidBody const *; + using reference = RigidBody const &; + using difference_type = std::ptrdiff_t; + //********************************************************************************************** + + //**Constructors******************************************************************************** + /*!\name Constructors */ + //@{ + inline ConstRigidBodyIterator() {} + inline ConstRigidBodyIterator( const RigidBodyIterator& it ) : it_(it.get()) {} + explicit inline ConstRigidBodyIterator( const typename ContainerType::iterator& it ) : it_(it) {} + explicit inline ConstRigidBodyIterator( const typename ContainerType::const_iterator& it ) : it_(it) {} + + ConstRigidBodyIterator( const ConstRigidBodyIterator& it) = default; + ConstRigidBodyIterator( ConstRigidBodyIterator&& it) = default; + + ConstRigidBodyIterator& operator=(const ConstRigidBodyIterator& it) = default; + ConstRigidBodyIterator& operator=(ConstRigidBodyIterator&& it) = default; + + //**Operators*********************************************************************************** + /*!\name Operators */ + //@{ + inline ConstRigidBodyIterator& operator++() {++it_; return *this;} + inline ConstRigidBodyIterator operator++( int ) {ConstRigidBodyIterator tmp(*this); ++(*this); return tmp;} + inline ConstRigidBodyIterator& operator--() {--it_; return *this;} + inline ConstRigidBodyIterator operator--( int ) {ConstRigidBodyIterator tmp(*this); --(*this); return tmp;} + inline ConstRigidBodyIterator& operator+=( difference_type n ) {it_ += n; return *this;} + inline ConstRigidBodyIterator operator+ ( difference_type n ) const {return ConstRigidBodyIterator( it_ + n );} + inline ConstRigidBodyIterator& operator-=( difference_type n ) {it_ -= n; return *this;} + inline ConstRigidBodyIterator operator- ( difference_type n ) const {return ConstRigidBodyIterator( it_ - n );} + inline difference_type operator- ( const ConstRigidBodyIterator& it ) const {return it_ - it.it_;} + //@} + //********************************************************************************************** + + //**Access operators**************************************************************************** + /*!\name Access operators */ + //@{ + inline reference operator[]( difference_type n ) const {return *it_[n];} + inline reference operator*() const {return **it_;} + inline pointer operator->() const {return it_->get();} + //@} + //********************************************************************************************** + + //**Utility functions*************************************************************************** + /*!\name Utility functions */ + //@{ + inline pointer getBodyID() const {return it_->get();} + inline ContainerType::const_iterator get() const {return it_;} + //@} + //********************************************************************************************** + +private: + //**Member variables**************************************************************************** + /*!\name Member variables */ + //@{ + typename ContainerType::const_iterator it_; //!< wrapped iterator + //@} + //********************************************************************************************** +}; +//************************************************************************************************* + + +//************************************************************************************************* +/*!\brief Equality comparison between two PtrIterator objects. + * + * \param lhs The left-hand side pointer iterator. + * \param rhs The right-hand side pointer iterator. + * \return \a true if the iterators point to the same element, \a false if not. + */ +inline bool operator==( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs ) +{ + return lhs.it_ == rhs.it_; +} +//************************************************************************************************* + + +//************************************************************************************************* +/*!\brief Inequality comparison between two PtrIterator objects. + * + * \param lhs The left-hand side pointer iterator. + * \param rhs The right-hand side pointer iterator. + * \return \a true if the iterators don't point to the same element, \a false if they do. + */ +inline bool operator!=( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs ) +{ + return !operator==(lhs, rhs); +} +//************************************************************************************************* + + +//************************************************************************************************* +/*!\brief Less-than comparison between two PtrIterator objects. + * + * \param lhs The left-hand side pointer iterator. + * \param rhs The right-hand side pointer iterator. + * \return \a true if the left-hand side iterator points to a lower element, \a false if not. + */ +inline bool operator<( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs ) +{ + return lhs.it_ < rhs.it_; +} +//************************************************************************************************* + + +//************************************************************************************************* +/*!\brief Greater-than comparison between two PtrIterator objects. + * + * \param lhs The left-hand side pointer iterator. + * \param rhs The right-hand side pointer iterator. + * \return \a true if the left-hand side iterator points to a higher element, \a false if not. + */ +inline bool operator>( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs ) +{ + return lhs.it_ > rhs.it_; +} +//************************************************************************************************* + + +//************************************************************************************************* +/*!\brief Less-or-equal-than comparison between two PtrIterator objects. + * + * \param lhs The left-hand side pointer iterator. + * \param rhs The right-hand side pointer iterator. + * \return \a true if the left-hand side iterator points to a lower or the same element, \a false if not. + */ +inline bool operator<=( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs ) +{ + return lhs.it_ <= rhs.it_; +} +//************************************************************************************************* + + +//************************************************************************************************* +/*!\brief Greater-or-equal-than comparison between two PtrIterator objects. + * + * \param lhs The left-hand side pointer iterator. + * \param rhs The right-hand side pointer iterator. + * \return \a true if the left-hand side iterator points to a higher or the same element, \a false if not. + */ +inline bool operator>=( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs ) +{ + return lhs.it_ >= rhs.it_; +} +//************************************************************************************************* + +} // namespace pe +} // namespace walberla diff --git a/src/pe/rigidbody/SphereFactory.cpp b/src/pe/rigidbody/SphereFactory.cpp index c9487031def01e2876e0d2bf6d341c1e9681825b..d88774c45f10803f84eaa1ac9f8fcd5a21fb91c6 100644 --- a/src/pe/rigidbody/SphereFactory.cpp +++ b/src/pe/rigidbody/SphereFactory.cpp @@ -26,6 +26,9 @@ #include "pe/rigidbody/BodyStorage.h" #include "pe/rigidbody/Sphere.h" +#include <core/logging/Logging.h> +#include <core/UniqueID.h> + namespace walberla { namespace pe { @@ -39,32 +42,31 @@ SphereID createSphere( BodyStorage& globalStorage, BlockStorage& blocks, BlockDa if( radius <= real_c(0) ) throw std::invalid_argument( "Invalid sphere radius" ); - SphereID sphere = NULL; + SphereID sphere = nullptr; if (global) { const id_t sid = UniqueID<RigidBody>::createGlobal(); WALBERLA_ASSERT_EQUAL(communicating, false); WALBERLA_ASSERT_EQUAL(infiniteMass, true); - sphere = new Sphere(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, material, global, false, true); - globalStorage.add(sphere); + SpherePtr sp = std::make_unique<Sphere>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, material, global, false, true); + sphere = static_cast<SphereID>(&globalStorage.add( std::move(sp) )); } else { - for (auto it = blocks.begin(); it != blocks.end(); ++it){ - IBlock* block = (&(*it)); - if (block->getAABB().contains(gpos)) + for (auto& block : blocks){ + if (block.getAABB().contains(gpos)) { const id_t sid( UniqueID<RigidBody>::create() ); - Storage* bs = block->getData<Storage>(storageID); - sphere = new Sphere(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, material, global, communicating, infiniteMass); - sphere->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block->getId().getID())); - (*bs)[0].add(sphere); + BodyStorage& bs = (*block.getData<Storage>(storageID))[0]; + SpherePtr sp = std::make_unique<Sphere>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, material, global, communicating, infiniteMass); + sp->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID())); + sphere = static_cast<SphereID>(&bs.add( std::move(sp) )); } } } - if (sphere != NULL) + if (sphere != nullptr) { // Logging the successful creation of the sphere WALBERLA_LOG_DETAIL( diff --git a/src/pe/rigidbody/SquirmerFactory.cpp b/src/pe/rigidbody/SquirmerFactory.cpp index 41b495b75aa008cf3aae1278b98ad450302b9cd7..7160ff2d0fa80e72dcf28a5f3fe7445e0679999f 100644 --- a/src/pe/rigidbody/SquirmerFactory.cpp +++ b/src/pe/rigidbody/SquirmerFactory.cpp @@ -24,6 +24,9 @@ #include "pe/rigidbody/BodyStorage.h" #include "pe/rigidbody/Squirmer.h" +#include <core/logging/Logging.h> +#include <core/UniqueID.h> + namespace walberla { namespace pe { @@ -38,32 +41,31 @@ SquirmerID createSquirmer( BodyStorage& globalStorage, BlockStorage& blocks, Blo if( radius <= real_c(0) ) throw std::invalid_argument( "Invalid squirmer radius" ); - SquirmerID squirmer = NULL; + SquirmerID squirmer = nullptr; if (global) { const id_t sid = UniqueID<RigidBody>::createGlobal(); WALBERLA_ASSERT_EQUAL(communicating, false); WALBERLA_ASSERT_EQUAL(infiniteMass, true); - squirmer = new Squirmer(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, squirmerVelocity, squirmerBeta, material, global, false, true); - globalStorage.add(squirmer); + SquirmerPtr sq = std::make_unique<Squirmer>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, squirmerVelocity, squirmerBeta, material, global, false, true); + squirmer = static_cast<SquirmerID>(&globalStorage.add(std::move(sq))); } else { - for (auto it = blocks.begin(); it != blocks.end(); ++it){ - IBlock* block = (&(*it)); - if (block->getAABB().contains(gpos)) + for (auto& block : blocks){ + if (block.getAABB().contains(gpos)) { const id_t sid( UniqueID<RigidBody>::create() ); - Storage* bs = block->getData<Storage>(storageID); - squirmer = new Squirmer(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, squirmerVelocity, squirmerBeta, material, global, communicating, infiniteMass); - squirmer->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block->getId().getID())); - (*bs)[0].add(squirmer); + BodyStorage& bs = (*block.getData<Storage>(storageID))[0]; + SquirmerPtr sq = std::make_unique<Squirmer>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, squirmerVelocity, squirmerBeta, material, global, communicating, infiniteMass); + sq->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID())); + squirmer = static_cast<SquirmerID>(&bs.add( std::move(sq) )); } } } - if (squirmer != NULL) + if (squirmer != nullptr) { // Logging the successful creation of the squirmer WALBERLA_LOG_DETAIL( diff --git a/src/pe/rigidbody/StorageDataHandling.h b/src/pe/rigidbody/StorageDataHandling.h index 6e3b0d2dafad64473a5b63f325e00bdccd49eb38..2d49a98c84b21d11d4c3bf51da230e62c648ebae 100644 --- a/src/pe/rigidbody/StorageDataHandling.h +++ b/src/pe/rigidbody/StorageDataHandling.h @@ -88,8 +88,8 @@ void StorageDataHandling<BodyTuple>::serialize( IBlock * const block, const Bloc { WALBERLA_ABORT( "Body to be stored not contained within block!" ); } - marshal( buffer, RigidBodyCopyNotification( **bodyIt ) ); - MarshalDynamically<BodyTuple>::execute( buffer, **bodyIt ); + marshal( buffer, RigidBodyCopyNotification( *bodyIt ) ); + MarshalDynamically<BodyTuple>::execute( buffer, *bodyIt ); } } @@ -146,8 +146,8 @@ void StorageDataHandling<BodyTuple>::serializeCoarseToFine( Block * const block, } if( childAABB.contains( bodyIt->getPosition()) ) { - marshal( buffer, RigidBodyCopyNotification( **bodyIt ) ); - MarshalDynamically<BodyTuple>::execute( buffer, **bodyIt ); + marshal( buffer, RigidBodyCopyNotification( *bodyIt ) ); + MarshalDynamically<BodyTuple>::execute( buffer, *bodyIt ); ++numOfParticles; } } @@ -166,8 +166,8 @@ void StorageDataHandling<BodyTuple>::serializeFineToCoarse( Block * const block, { WALBERLA_ABORT( "Body to be stored not contained within block!" ); } - marshal( buffer, RigidBodyCopyNotification( **bodyIt ) ); - MarshalDynamically<BodyTuple>::execute( buffer, **bodyIt ); + marshal( buffer, RigidBodyCopyNotification( *bodyIt ) ); + MarshalDynamically<BodyTuple>::execute( buffer, *bodyIt ); } } @@ -214,16 +214,16 @@ void StorageDataHandling<BodyTuple>::deserializeImpl( IBlock * const block, cons typename RigidBodyCopyNotification::Parameters objparam; unmarshal( buffer, objparam ); - BodyID bd = UnmarshalDynamically<BodyTuple>::execute(buffer, objparam.geomType_, block->getBlockStorage().getDomain(), block->getAABB()); + auto bd = UnmarshalDynamically<BodyTuple>::execute(buffer, objparam.geomType_, block->getBlockStorage().getDomain(), block->getAABB()); bd->setRemote( false ); bd->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block->getId().getID())); if ( !block->getAABB().contains( bd->getPosition()) ) { - WALBERLA_ABORT("Loaded body not contained within block!\n" << "aabb: " << block->getAABB() << "\nparticle:" << bd ); + WALBERLA_ABORT("Loaded body not contained within block!\n" << "aabb: " << block->getAABB() << "\nparticle:" << *bd ); } WALBERLA_ASSERT_EQUAL(localBodyStorage.find( bd->getSystemID() ), localBodyStorage.end()); - localBodyStorage.add(bd); + localBodyStorage.add(std::move(bd)); --numBodies; } diff --git a/src/pe/rigidbody/Union.h b/src/pe/rigidbody/Union.h index 81c8128f6a4253f8d17f43801fef4a39f9e056b7..fe6e0ce94f1e975feaae4cea68b97aa6aa85ad1d 100644 --- a/src/pe/rigidbody/Union.h +++ b/src/pe/rigidbody/Union.h @@ -27,7 +27,10 @@ //************************************************************************************************* #include <pe/Config.h> +#include <pe/rigidbody/BodyStorage.h> #include <pe/rigidbody/RigidBody.h> +#include <pe/rigidbody/RigidBodyCastIterator.h> +#include <pe/rigidbody/RigidBodyIterator.h> #include <pe/Types.h> #include <core/debug/Debug.h> @@ -65,23 +68,24 @@ class Union : public RigidBody { public: //**Type definitions**************************************************************************** - typedef BodyTypeTuple BodyTypeTupleT; + using BodyTypeTupleT = BodyTypeTuple; - typedef PtrVector<RigidBody, PtrDelete> Bodies; //!< Iterator over the contained rigid bodies. - typedef Bodies::Iterator Iterator; //!< Iterator over the contained rigid bodies. - typedef Bodies::ConstIterator ConstIterator; //!< Constant iterator over the contained rigid bodies. - //**++++++++++++++++**************************************************************************** + //********************************************************************************************** - //**Forward declarations for nested classes***************************************************** -// template< typename C > class CastIterator; -// template< typename C > class ConstCastIterator; + using size_type = BodyStorage::size_type; //!< Size type of the body storage. + using iterator = BodyStorage::iterator; //!< Iterator over non-const bodies. + using const_iterator = BodyStorage::const_iterator; //!< Iterator over constant bodies. + template <typename C> //cast type + using cast_iterator = BodyStorage::cast_iterator<C>; + template <typename C> //cast type + using const_cast_iterator = BodyStorage::const_cast_iterator<C>; //********************************************************************************************** //**Constructors******************************************************************************** /*!\name Constructors */ //@{ explicit Union( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q, - const bool global, const bool communicating, const bool infiniteMass ); + const bool global, const bool communicating, const bool infiniteMass ); //@} //********************************************************************************************** @@ -95,28 +99,35 @@ public: public: //**Get functions******************************************************************************* - /*!\name Get functions */ + /*!\name BodyStorage functions */ //@{ - inline bool isEmpty() const; - inline size_t size() const; - template< typename C > inline size_t size() const {return bodies_.size<C>();} - inline BodyID getBody( size_t index ); - inline ConstBodyID getBody( size_t index ) const; - - inline Iterator begin() {return bodies_.begin();} - inline ConstIterator begin() const {return bodies_.begin();} - template< typename C > inline Bodies::CastIterator<C> begin() {return bodies_.begin<C>();} - template< typename C > inline Bodies::ConstCastIterator<C> begin() const {return bodies_.begin<C>();} - - inline Iterator end() {return bodies_.end();} - inline ConstIterator end() const {return bodies_.end();} - template< typename C > inline Bodies::CastIterator<C> end() {return bodies_.end<C>();} - template< typename C > inline Bodies::ConstCastIterator<C> end() const {return bodies_.end<C>();} - - virtual inline real_t getVolume() const; + inline bool isEmpty() const {return bodies_.isEmpty();} + inline size_t size() const {return bodies_.size();} + + inline iterator begin () {return bodies_.begin();} + inline const_iterator begin () const {return bodies_.begin();} + inline const_iterator cbegin () const {return bodies_.cbegin();} + inline iterator end () {return bodies_.end();} + inline const_iterator end () const {return bodies_.end();} + inline const_iterator cend () const {return bodies_.cend();} + + template< typename C > + inline cast_iterator<C> begin() {return bodies_.begin<C>();} + template< typename C > + inline const_cast_iterator<C> begin() const {return bodies_.begin<C>();} + template< typename C > + inline const_cast_iterator<C> cbegin() const {return bodies_.cbegin<C>();} + template< typename C > + inline cast_iterator<C> end() {return bodies_.end<C>();} + template< typename C > + inline const_cast_iterator<C> end() const {return bodies_.end<C>();} + template< typename C > + inline const_cast_iterator<C> cend() const {return bodies_.cend<C>();} //@} //********************************************************************************************** + virtual inline real_t getVolume() const; + //**Set functions******************************************************************************* /*!\name Set functions */ //@{ @@ -146,7 +157,7 @@ public: //**Rigid body manager functions**************************************************************** /*!\name Rigid body manager functions */ //@{ - void add ( BodyID body ); + inline RigidBody& add( std::unique_ptr<RigidBody>&& body ); //@} //********************************************************************************************** @@ -183,18 +194,13 @@ protected: /*!\name Utility functions */ //@{ inline virtual void calcBoundingBox() WALBERLA_OVERRIDE; // Calculation of the axis-aligned bounding box - void calcCenterOfMass(); ///< updates the center of mass (gpos) + void calcCenterOfMass(); ///< updates the center of mass (gpos) inline void calcInertia(); // Calculation of the moment of inertia //@} //********************************************************************************************** - //**Member variables**************************************************************************** - /*!\name Member variables */ - //@{ - PtrVector<RigidBody, PtrDelete> bodies_; //!< Rigid bodies contained in the union. - //@} - //********************************************************************************************** private: + BodyStorage bodies_; //!< Rigid bodies contained in the union. std::vector<id_t> containedTypeIDs_; static id_t staticTypeID_; //< type id of sphere, will be set by SetBodyTypeIDs @@ -228,7 +234,7 @@ private: */ template <typename BodyTypeTuple> Union<BodyTypeTuple>::Union( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q, - const bool global, const bool communicating, const bool /*infiniteMass*/ ) + const bool global, const bool communicating, const bool /*infiniteMass*/ ) : RigidBody( getStaticTypeID(), sid, uid ) // Initialization of the parent class { // Initializing the instantiated union @@ -241,7 +247,7 @@ Union<BodyTypeTuple>::Union( id_t sid, id_t uid, const Vec3& gpos, const Vec3& r calcInertia(); setGlobal( global ); -// setMass( infiniteMass ); + // setMass( infiniteMass ); setCommunicating( communicating ); setFinite( true ); } @@ -322,7 +328,7 @@ void Union<BodyTypeTuple>::calcBoundingBox() // Setting the bounding box of an empty union if( bodies_.isEmpty() ) { aabb_ = math::AABB( - gpos_[0] - real_t(0.01), + gpos_[0] - real_t(0.01), gpos_[1] - real_t(0.01), gpos_[2] - real_t(0.01), gpos_[0] + real_t(0.01), @@ -334,7 +340,7 @@ void Union<BodyTypeTuple>::calcBoundingBox() // Using the bounding box of the first contained bodies as initial bounding box // and merging it with the bounding boxes of all other bodies else { - aabb_ = bodies_[0]->getAABB(); + aabb_ = bodies_.begin()->getAABB(); for( auto b=bodies_.begin()+1; b!=bodies_.end(); ++b ) aabb_.merge( b->getAABB() ); } @@ -366,7 +372,7 @@ void Union<BodyTypeTuple>::calcCenterOfMass() // Calculating the center of mass of a single body if( bodies_.size() == 1 ) { - const BodyID body( bodies_[0] ); + const BodyID body( bodies_.begin().getBodyID() ); gpos_ = body->getPosition(); mass_ = body->getMass(); if( !isFixed() && mass_ > real_t(0) ) @@ -512,8 +518,8 @@ void Union<BodyTypeTuple>::setPositionImpl( real_t px, real_t py, real_t pz ) gpos_ = gpos; // Updating the contained bodies - for( auto b=bodies_.begin(); b!=bodies_.end(); ++b ) - (*b)->update( dp ); + for( auto& b : bodies_ ) + b.update( dp ); Union<BodyTypeTuple>::calcBoundingBox(); // Setting the axis-aligned bounding box wake(); // Waking the union from sleep mode @@ -548,8 +554,8 @@ void Union<BodyTypeTuple>::setOrientationImpl( real_t r, real_t i, real_t j, rea R_ = q_.toRotationMatrix(); // Updating the contained bodies - for( auto b=bodies_.begin(); b!=bodies_.end(); ++b ) - (*b)->update( dq ); + for( auto& b : bodies_ ) + b.update( dq ); Union<BodyTypeTuple>::calcBoundingBox(); // Setting the axis-aligned bounding box wake(); // Waking the union from sleep mode @@ -586,8 +592,8 @@ void Union<BodyTypeTuple>::update( const Vec3& dp ) gpos_ += dp; // Updating the contained bodies - for( auto b=bodies_.begin(); b!=bodies_.end(); ++b ) - (*b)->update( dp ); + for( auto& b : bodies_ ) + b.update( dp ); // Setting the axis-aligned bounding box Union<BodyTypeTuple>::calcBoundingBox(); @@ -623,8 +629,8 @@ void Union<BodyTypeTuple>::update( const Quat& dq ) R_ = q_.toRotationMatrix(); // Updating the contained bodies - for( auto b=bodies_.begin(); b!=bodies_.end(); ++b ) - (*b)->update( dq ); + for( auto& b : bodies_ ) + b.update( dq ); // Setting the axis-aligned bounding box Union<BodyTypeTuple>::calcBoundingBox(); @@ -694,38 +700,38 @@ void Union<BodyTypeTuple>::update( const Quat& dq ) * union (to make the entire union (in-)visible. */ template <typename BodyTypeTuple> -void Union<BodyTypeTuple>::add( BodyID body ) +RigidBody& Union<BodyTypeTuple>::add( std::unique_ptr<RigidBody>&& body ) { // Checking for "self-assignment" - if( body == BodyID( this ) ) return; + if( body.get() == BodyID( this ) ) return *this; // Checking the global flags of the body and the union in MPI parallel simulations if( body->isGlobal() ^ global_ ) throw std::logic_error( "Global flags of body and union do not match" ); + // Registering the rigid body + auto& bd = bodies_.add( std::move(body) ); + Vec3 oldCenterOfMass = getPosition(); Vec3 oldImpulse = getLinearVel() * getMass(); - Vec3 bodyCenterOfMass = body->getPosition(); - Vec3 bodyImpulse = body->getLinearVel() * body->getMass(); + Vec3 bodyCenterOfMass = bd.getPosition(); + Vec3 bodyImpulse = bd.getLinearVel() * bd.getMass(); - - // Registering the rigid body - body->setSB(this); - bodies_.pushBack( body ); + bd.setSB(this); //having a superbody will forward all getVel calls to superbody!!! // Updating the axis-aligned bounding box if( bodies_.size() == 1 ) - aabb_ = body->getAABB(); + aabb_ = bd.getAABB(); else - aabb_.merge( body->getAABB() ); + aabb_.merge( bd.getAABB() ); // Setting the union's total mass and center of mass calcCenterOfMass(); // Setting the contained primitives' relative position in reference to the center of mass - for( auto b=bodies_.begin(); b!=bodies_.end(); ++b ) - ( *b )->calcRelPosition(); + for( auto& b : bodies_ ) + b.calcRelPosition(); // Setting the moment of inertia calcInertia(); @@ -735,11 +741,13 @@ void Union<BodyTypeTuple>::add( BodyID body ) setAngularVel( Vec3(0,0,0) ); addImpulseAtPos( oldImpulse, oldCenterOfMass); addImpulseAtPos( bodyImpulse, bodyCenterOfMass); - body->setLinearVel( Vec3(0,0,0) ); - body->setAngularVel( Vec3(0,0,0) ); + bd.setLinearVel( Vec3(0,0,0) ); + bd.setAngularVel( Vec3(0,0,0) ); // Signaling the internal modification to the superordinate body signalModification(); + + return bodies_.back(); } //************************************************************************************************* @@ -771,8 +779,8 @@ void Union<BodyTypeTuple>::translateImpl( real_t dx, real_t dy, real_t dz ) gpos_ += dp; // Updating the contained bodies - for( auto b=bodies_.begin(); b!=bodies_.end(); ++b ) - (*b)->update( dp ); + for( auto& b : bodies_ ) + b.update( dp ); Union<BodyTypeTuple>::calcBoundingBox(); // Setting the axis-aligned bounding box wake(); // Waking the union from sleep mode @@ -811,8 +819,8 @@ void Union<BodyTypeTuple>::rotateImpl( const Quat& dq ) R_ = q_.toRotationMatrix(); // Updating the rotation of the union // Updating the contained bodies - for( auto b=bodies_.begin(); b!=bodies_.end(); ++b ) - (*b)->update( dq ); + for( auto& b : bodies_ ) + b.update( dq ); Union<BodyTypeTuple>::calcBoundingBox(); // Setting the axis-aligned bounding box wake(); // Waking the union from sleep mode @@ -843,8 +851,8 @@ void Union<BodyTypeTuple>::rotateAroundOriginImpl( const Quat& dq ) gpos_ = dq.rotate( gpos_ ); // Updating the global position of the union // Updating the contained bodies - for( auto b=bodies_.begin(); b!=bodies_.end(); ++b ) - (*b)->update( dq ); + for( auto& b : bodies_ ) + b.update( dq ); Union<BodyTypeTuple>::calcBoundingBox(); // Setting the axis-aligned bounding box wake(); // Waking the union from sleep mode @@ -876,8 +884,8 @@ void Union<BodyTypeTuple>::rotateAroundPointImpl( const Vec3& point, const Quat gpos_ = point + dq.rotate( dp ); // Updating the global position of the union // Updating the contained bodies - for( auto b=bodies_.begin(); b!=bodies_.end(); ++b ) - (*b)->update( dq ); + for( auto& b : bodies_ ) + b.update( dq ); Union<BodyTypeTuple>::calcBoundingBox(); // Setting the axis-aligned bounding box wake(); // Waking the union from sleep mode @@ -906,8 +914,8 @@ template <typename BodyTypeTuple> bool Union<BodyTypeTuple>::containsRelPointImpl( real_t px, real_t py, real_t pz ) const { const Vec3 gpos( pointFromBFtoWF( px, py, pz ) ); - for( auto b=bodies_.begin(); b!=bodies_.end(); ++b ) - if( b->containsPoint( gpos ) ) return true; + for( auto& b : bodies_ ) + if( b.containsPoint( gpos ) ) return true; return false; } //************************************************************************************************* @@ -929,9 +937,10 @@ bool Union<BodyTypeTuple>::isSurfaceRelPointImpl( real_t px, real_t py, real_t p bool surface( false ); const Vec3 gpos( pointFromBFtoWF( px, py, pz ) ); - for( auto b=bodies_.begin(); b!=bodies_.end(); ++b ) { - if( b->containsPoint( gpos ) ) return false; - else if( b->isSurfacePoint( gpos ) ) surface = true; + for( auto& b : bodies_ ) + { + if( b.containsPoint( gpos ) ) return false; + else if( b.isSurfacePoint( gpos ) ) surface = true; } return surface; @@ -974,8 +983,8 @@ void Union<BodyTypeTuple>::handleModification() calcCenterOfMass(); // Setting the contained primitives' relative position in reference to the center of mass - for( auto b=bodies_.begin(); b!=bodies_.end(); ++b ) - ( *b )->calcRelPosition(); + for( auto& b : bodies_ ) + b.calcRelPosition(); // Setting the moment of inertia calcInertia(); @@ -1004,8 +1013,8 @@ void Union<BodyTypeTuple>::handleTranslation() calcCenterOfMass(); // Setting the contained bodies' relative position in reference to the center of mass - for( auto b=bodies_.begin(); b!=bodies_.end(); ++b ) - ( *b )->calcRelPosition(); + for( auto& b : bodies_ ) + b.calcRelPosition(); // Setting the moment of inertia calcInertia(); @@ -1155,65 +1164,6 @@ std::ostream& operator<<( std::ostream& os, Union<BodyTypeTuple> const * u ) // //================================================================================================= -//************************************************************************************************* -/*!\brief Returns whether the union contains any bodies or not. - * - * \return \a true if the union is empty, \a false if it not. - */ -template <typename BodyTypeTuple> -inline bool Union<BodyTypeTuple>::isEmpty() const -{ - return bodies_.size() == 0; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns the number of rigid bodies contained in the union. - * - * \return The number of rigid bodies. - */ -template <typename BodyTypeTuple> -inline size_t Union<BodyTypeTuple>::size() const -{ - return bodies_.size(); -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns a handle to the indexed rigid body. - * - * \param index Access index. The index has to be in the range \f$[0..size-1]\f$. - * \return Handle to the accessed body. - * - * \b Note: No runtime check is performed to insure the validity of the access index. - */ -template <typename BodyTypeTuple> -inline BodyID Union<BodyTypeTuple>::getBody( size_t index ) -{ - WALBERLA_ASSERT_LESS( index, bodies_.size(), "Invalid access index" ); - return bodies_[index]; -} -//************************************************************************************************* - - -//************************************************************************************************* -/*!\brief Returns a constant handle to the indexed rigid body. - * - * \param index Access index. The index has to be in the range \f$[0..size-1]\f$. - * \return Constant handle to the accessed body. - * - * \b Note: No runtime check is performed to insure the validity of the access index. - */ -template <typename BodyTypeTuple> -inline ConstBodyID Union<BodyTypeTuple>::getBody( size_t index ) const -{ - WALBERLA_ASSERT_LESS( index, bodies_.size(), "Invalid access index" ); - return bodies_[index]; -} -//************************************************************************************************* - //************************************************************************************************* /*!\brief Returns unique type id of this type diff --git a/src/pe/rigidbody/UnionFactory.h b/src/pe/rigidbody/UnionFactory.h index e237e0dd31d83642f80663ed48b7c083498cad63..eeff2ffe8c578fe05924c8fea440afb89b33e5e2 100644 --- a/src/pe/rigidbody/UnionFactory.h +++ b/src/pe/rigidbody/UnionFactory.h @@ -31,8 +31,10 @@ #include "pe/rigidbody/Union.h" #include "pe/Types.h" -#include "blockforest/BlockForest.h" -#include "core/debug/Debug.h" +#include <blockforest/BlockForest.h> +#include <core/debug/Debug.h> +#include <core/logging/Logging.h> +#include <core/UniqueID.h> namespace walberla { namespace pe { @@ -73,32 +75,31 @@ Union<BodyTypeTuple>* createUnion( BodyStorage& globalStorage, BlockStorage& b if (Union<BodyTypeTuple>::getStaticTypeID() == std::numeric_limits<id_t>::max()) throw std::runtime_error("Union TypeID not initalized!"); - Union<BodyTypeTuple>* bd = NULL; + Union<BodyTypeTuple>* bd = nullptr; if (global) { const id_t sid = UniqueID<RigidBody>::createGlobal(); WALBERLA_ASSERT_EQUAL(communicating, false); WALBERLA_ASSERT_EQUAL(infiniteMass, true); - bd = new Union<BodyTypeTuple>(sid, uid, gpos, Vec3(0,0,0), Quat(), global, false, true); - globalStorage.add(bd); + auto un = std::make_unique<Union<BodyTypeTuple>>(sid, uid, gpos, Vec3(0,0,0), Quat(), global, false, true); + bd = static_cast<Union<BodyTypeTuple>*>(&globalStorage.add(std::move(un))); } else { - for (auto it = blocks.begin(); it != blocks.end(); ++it){ - IBlock* block = (&(*it)); - if (block->getAABB().contains(gpos)) + for (auto& block : blocks){ + if (block.getAABB().contains(gpos)) { const id_t sid( UniqueID<RigidBody>::create() ); - Storage* bs = block->getData<Storage>(storageID); - bd = new Union<BodyTypeTuple>(sid, uid, gpos, Vec3(0,0,0), Quat(), global, communicating, infiniteMass); - bd->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block->getId().getID())); - (*bs)[0].add(bd); + BodyStorage& bs = (*block.getData<Storage>(storageID))[0]; + auto un = std::make_unique<Union<BodyTypeTuple>>(sid, uid, gpos, Vec3(0,0,0), Quat(), global, communicating, infiniteMass); + un->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID())); + bd = static_cast<Union<BodyTypeTuple>*>(&bs.add(std::move(un))); } } } - if (bd != NULL) + if (bd != nullptr) { // Logging the successful creation of the box WALBERLA_LOG_DETAIL( @@ -143,7 +144,6 @@ BoxID createBox( Union<BodyTypeTuple>* un, if( lengths[0] <= real_t(0) || lengths[1] <= real_t(0) || lengths[2] <= real_t(0) ) throw std::invalid_argument( "Invalid side length" ); - BoxID box = NULL; id_t sid = 0; if (global) @@ -156,9 +156,8 @@ BoxID createBox( Union<BodyTypeTuple>* un, sid = UniqueID<RigidBody>::create(); } - box = new Box(sid, uid, gpos, Vec3(0,0,0), Quat(), lengths, material, global, communicating, infiniteMass); + std::unique_ptr<Box> box = std::make_unique<Box>(sid, uid, gpos, Vec3(0,0,0), Quat(), lengths, material, global, communicating, infiniteMass); box->MPITrait.setOwner( un->MPITrait.getOwner() ); - un->add(box); if (box != NULL) { @@ -173,7 +172,7 @@ BoxID createBox( Union<BodyTypeTuple>* un, ); } - return box; + return static_cast<BoxID> (&(un->add(std::move(box)))); } //************************************************************************************************* @@ -215,7 +214,6 @@ CapsuleID createCapsule( Union<BodyTypeTuple>* un, if( length <= real_c(0) ) throw std::invalid_argument( "Invalid capsule length" ); - CapsuleID capsule = NULL; id_t sid = 0; if (global) @@ -228,16 +226,15 @@ CapsuleID createCapsule( Union<BodyTypeTuple>* un, sid = UniqueID<RigidBody>::create(); } - capsule = new Capsule(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, length, material, global, communicating, infiniteMass); + std::unique_ptr<Capsule> capsule = std::make_unique<Capsule>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, length, material, global, communicating, infiniteMass); capsule->MPITrait.setOwner( un->MPITrait.getOwner() ); - un->add(capsule); if (capsule != NULL) { - WALBERLA_LOG_DETAIL("Created capsule " << capsule->getSystemID() << "\n" << capsule); + WALBERLA_LOG_DETAIL("Created capsule " << capsule->getSystemID() << "\n" << *capsule); } - return capsule; + return static_cast<CapsuleID>(&(un->add(std::move(capsule)))); } //************************************************************************************************* @@ -275,7 +272,6 @@ SphereID createSphere( Union<BodyTypeTuple>* un, throw std::invalid_argument( "Invalid sphere radius" ); id_t sid(0); - SphereID sphere = NULL; if (global) { @@ -288,9 +284,8 @@ SphereID createSphere( Union<BodyTypeTuple>* un, sid = UniqueID<RigidBody>::create(); } - sphere = new Sphere(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, material, global, communicating, infiniteMass); + std::unique_ptr<Sphere> sphere = std::make_unique<Sphere>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, material, global, communicating, infiniteMass); sphere->MPITrait.setOwner( un->MPITrait.getOwner() ); - un->add( sphere ); if (sphere != NULL) { @@ -305,7 +300,7 @@ SphereID createSphere( Union<BodyTypeTuple>* un, ); } - return sphere; + return static_cast<SphereID>(&(un->add( std::move(sphere) ))); } } // namespace pe diff --git a/src/pe/synchronization/RemoveAndNotify.h b/src/pe/synchronization/RemoveAndNotify.h index 8eaf880fe6e80157b7199d37dbf5b75606925a53..6c8d27c0d89e6e7ec2f9cc34464f9c28c3593d4e 100644 --- a/src/pe/synchronization/RemoveAndNotify.h +++ b/src/pe/synchronization/RemoveAndNotify.h @@ -44,7 +44,7 @@ namespace pe { * This function removes the rigid body from the body storage and generates deletion notifications. */ inline -BodyStorage::Iterator removeAndNotify( Owner me, mpi::BufferSystem& bs, BodyStorage& localStorage, BodyStorage::Iterator body ) +BodyStorage::iterator removeAndNotify( Owner me, mpi::BufferSystem& bs, BodyStorage& localStorage, BodyStorage::iterator body ) { using namespace walberla::pe::communication; @@ -57,7 +57,7 @@ BodyStorage::Iterator removeAndNotify( Owner me, mpi::BufferSystem& bs, BodyStor WALBERLA_LOG_DETAIL( "__Notify registered process " << (*it) << " of deletion of body " << body->getSystemID() ); mpi::SendBuffer& sb = bs.sendBuffer(it->rank_); if (sb.isEmpty()) sb << walberla::uint8_c(0); - packNotification(me, *it, sb, RigidBodyDeletionNotification( **body )); + packNotification(me, *it, sb, RigidBodyDeletionNotification( *body )); } } diff --git a/src/pe/synchronization/SyncForces.h b/src/pe/synchronization/SyncForces.h index 0bca535418797cfdfdf9f18979a169f607f80e87..aa83e65196722fd0fea23a262671ea97919de3ff 100644 --- a/src/pe/synchronization/SyncForces.h +++ b/src/pe/synchronization/SyncForces.h @@ -74,7 +74,7 @@ void reduceForces( BlockStorage& blocks, BlockDataID storageID ) WALBERLA_LOG_DETAIL( "__Sending force contribution " << bodyIt->getForce() << ", " << bodyIt->getTorque() << " of body " << bodyIt->getSystemID() << " to owner block " << bodyIt->MPITrait.getOwner().blockID_ << ".\n"); - packNotification(me, bodyIt->MPITrait.getOwner(), sb, RigidBodyForceNotification( *(*bodyIt) ) ); + packNotification(me, bodyIt->MPITrait.getOwner(), sb, RigidBodyForceNotification( *bodyIt ) ); } @@ -135,7 +135,7 @@ void reduceForces( BlockStorage& blocks, BlockDataID storageID, BodyStorage& glo { if (it->hasInfiniteMass()) continue; - const Vec3 f( (*it)->getForce() ), tau( (*it)->getTorque() ); + const Vec3 f( it->getForce() ), tau( it->getTorque() ); reductionBuffer[i++] = f[0]; reductionBuffer[i++] = f[1]; reductionBuffer[i++] = f[2]; @@ -150,8 +150,8 @@ void reduceForces( BlockStorage& blocks, BlockDataID storageID, BodyStorage& glo for( auto it = globalBodyStorage.begin(); it != globalBodyStorage.end(); ++it ) { if (it->hasInfiniteMass()) continue; - (*it)->setForce ( Vec3( reductionBuffer[i], reductionBuffer[i + 1], reductionBuffer[i + 2] ) ); - (*it)->setTorque( Vec3( reductionBuffer[i + 3], reductionBuffer[i + 4], reductionBuffer[i + 5] ) ); + it->setForce ( Vec3( reductionBuffer[i], reductionBuffer[i + 1], reductionBuffer[i + 2] ) ); + it->setTorque( Vec3( reductionBuffer[i + 3], reductionBuffer[i + 4], reductionBuffer[i + 5] ) ); } } WALBERLA_LOG_DETAIL( "Sync force on global bodies finished." ); @@ -198,7 +198,7 @@ void distributeForces( BlockStorage& blocks, BlockDataID storageID ) WALBERLA_LOG_DETAIL( "__Sending force contribution " << bodyIt->getForce() << ", " << bodyIt->getTorque() << " of body " << bodyIt->getSystemID() << " to shadow owner " << sownerIt->blockID_ << ".\n"); - packNotification(me, *sownerIt, sb, RigidBodyForceNotification( *(*bodyIt) ) ); + packNotification(me, *sownerIt, sb, RigidBodyForceNotification( *bodyIt ) ); } } diff --git a/src/pe/synchronization/SyncNextNeighbors.h b/src/pe/synchronization/SyncNextNeighbors.h index 56da2bc958e39edf2994882fcc9e2b69fd5d2c77..63aa9a2081db232e11a8677cca8eec6253c7fd40 100644 --- a/src/pe/synchronization/SyncNextNeighbors.h +++ b/src/pe/synchronization/SyncNextNeighbors.h @@ -67,7 +67,7 @@ void generateSynchonizationMessages(mpi::BufferSystem& bs, const Block& block, B } const Vec3 gpos( body->getPosition() ); - BodyID b ( *body ); + BodyID b ( body.getBodyID() ); if (body->isMarkedForDeletion()) { @@ -155,7 +155,7 @@ void generateSynchonizationMessages(mpi::BufferSystem& bs, const Block& block, B WALBERLA_LOG_DETAIL( "Sending deletion notifications for body " << body->getSystemID() << " due to outflow." ); // Registered processes receive removal notification in the remove() routine. - //todelete.push_back( *body ); + //todelete.push_back( body.getBodyID() ); body = removeAndNotify( me, bs, localStorage, body ); // Note: Attached shadow copies are not deleted here. Instead we rely on the deferred deletion since we no @@ -189,8 +189,7 @@ void generateSynchonizationMessages(mpi::BufferSystem& bs, const Block& block, B b->setRemote( true ); // Move body to shadow copy storage. - body = localStorage.release( body ); - shadowStorage.add( b ); + shadowStorage.add( localStorage.release( body ) ); // Note: We cannot determine here whether we require the body since we do not have up to date shadow copies. // However, we will most likely have to keep the body since it typically still intersects the process subdomain. diff --git a/src/pe/synchronization/SyncShadowOwners.h b/src/pe/synchronization/SyncShadowOwners.h index e02cea958b435d39f54e749aa237c696cec6d8ca..cc0400d11d50f78597a9be5fd53666c84f386ae0 100644 --- a/src/pe/synchronization/SyncShadowOwners.h +++ b/src/pe/synchronization/SyncShadowOwners.h @@ -79,7 +79,7 @@ void updateAndMigrate( BlockForest& forest, BlockDataID storageID, const bool sy for( auto bodyIt = localStorage.begin(); bodyIt != localStorage.end(); ) { - BodyID b (*bodyIt); + BodyID b (bodyIt.getBodyID()); if( !b->isCommunicating() && !syncNonCommunicatingBodies ) { ++bodyIt; @@ -131,8 +131,7 @@ void updateAndMigrate( BlockForest& forest, BlockDataID storageID, const bool sy b->setRemote( true ); // Move body to shadow copy storage. - bodyIt = localStorage.release( bodyIt ); - shadowStorage.add( b ); + shadowStorage.add( localStorage.release( bodyIt ) ); b->MPITrait.deregisterShadowOwner( owner ); @@ -220,7 +219,7 @@ void checkAndResolveOverlap( BlockForest& forest, BlockDataID storageID, const r for( auto bodyIt = localStorage.begin(); bodyIt != localStorage.end(); ++bodyIt) { - BodyID b (*bodyIt); + BodyID b (bodyIt.getBodyID()); if( !b->isCommunicating() && !syncNonCommunicatingBodies ) continue; @@ -256,7 +255,7 @@ void checkAndResolveOverlap( BlockForest& forest, BlockDataID storageID, const r } for( auto bodyIt = shadowStorage.begin(); bodyIt != shadowStorage.end(); ) { - BodyID b (*bodyIt); + BodyID b (bodyIt.getBodyID()); WALBERLA_ASSERT(!b->isGlobal(), "Global body in ShadowStorage!"); bool isInsideDomain = forest.getDomain().contains( b->getAABB(), -dx ); diff --git a/src/pe/utility/CreateWorld.cpp b/src/pe/utility/CreateWorld.cpp index 3ede915c665701c38248f1a3e25d2b55552fca81..919840085ee8b298083a7fcafa13c51488c5fd9a 100644 --- a/src/pe/utility/CreateWorld.cpp +++ b/src/pe/utility/CreateWorld.cpp @@ -79,7 +79,7 @@ std::unique_ptr<SetupBlockForest> createSetupBlockForest(const math::AABB simula blocks[2] = 2; } - auto sforest = std::unique_ptr<SetupBlockForest>( new SetupBlockForest() ); + auto sforest = std::make_unique<SetupBlockForest>( ); sforest->addWorkloadMemorySUIDAssignmentFunction( blockforest::uniformWorkloadAndMemoryAssignment ); sforest->addRefinementSelectionFunction( FixedRefinementLevelSelector(initialRefinementLevel) ); sforest->init( simulationDomain, blocks[0], blocks[1], blocks[2], isPeriodic[0], isPeriodic[1], isPeriodic[2] ); @@ -103,7 +103,7 @@ shared_ptr<BlockForest> createBlockForest(const math::AABB simulationDomain, } std::unique_ptr<SetupBlockForest> sforest( createSetupBlockForest( simulationDomain, blocks, isPeriodic, numberOfProcesses, initialRefinementLevel )); - return shared_ptr< BlockForest >( new BlockForest( uint_c( MPIManager::instance()->rank() ), *sforest, false ) ); + return std::make_shared< BlockForest >( uint_c( MPIManager::instance()->rank() ), *sforest, false ); } shared_ptr<BlockForest> createBlockForest(const math::AABB simulationDomain, @@ -142,13 +142,13 @@ shared_ptr<BlockForest> createBlockForest(const math::AABB simulationDomain, WALBERLA_LOG_INFO_ON_ROOT( "Production Run!" ); WALBERLA_LOG_INFO_ON_ROOT( "Creating the block structure: loading from file \'" << sbffile << "\' ..." ); - return shared_ptr< BlockForest >( new BlockForest( uint_c( MPIManager::instance()->rank() ), sbffile.c_str(), true, false ) ); + return std::make_shared< BlockForest >( uint_c( MPIManager::instance()->rank() ), sbffile.c_str(), true, false ); } shared_ptr<BlockForest> createBlockForestFromConfig(const Config::BlockHandle& mainConf) { - bool setupRun = mainConf.getParameter< bool >( "setupRun", true ); + bool setupRun = mainConf.getParameter< bool >( "setupRun", false ); Vec3 simulationCorner = mainConf.getParameter<Vec3>("simulationCorner", Vec3(0, 0, 0)); Vec3 simulationSize = mainConf.getParameter<Vec3>("simulationDomain", Vec3(10, 10, 10)); math::AABB simulationDomain = math::AABB( simulationCorner, simulationCorner + simulationSize ); diff --git a/src/pe/utility/DestroyBody.h b/src/pe/utility/DestroyBody.h index 189203fda04a9ed28db4049a2e1044ee8078bf39..20da0f1c86a8d84596e674adc1045b89c9b1ce13 100644 --- a/src/pe/utility/DestroyBody.h +++ b/src/pe/utility/DestroyBody.h @@ -49,7 +49,7 @@ void destroyBody(BodyStorage& globalStorage, BlockStorage& blocks, BlockDataID s { for (auto bodyIt = globalStorage.begin(); bodyIt != globalStorage.end(); ) { - if ( p(*bodyIt) ) + if ( p(bodyIt.getBodyID()) ) { bodyIt = globalStorage.remove( bodyIt ); } else @@ -68,7 +68,7 @@ void destroyBody(BodyStorage& globalStorage, BlockStorage& blocks, BlockDataID s BodyStorage& localStorage = storage[StorageType::LOCAL]; for (auto bodyIt = localStorage.begin(); bodyIt != localStorage.end(); ) { - if ( p(*bodyIt) ) + if ( p(bodyIt.getBodyID()) ) { bodyIt = localStorage.remove( bodyIt ); } else @@ -82,7 +82,7 @@ void destroyBody(BodyStorage& globalStorage, BlockStorage& blocks, BlockDataID s BodyStorage& shadowStorage = storage[StorageType::SHADOW]; for (auto bodyIt = shadowStorage.begin(); bodyIt != shadowStorage.end(); ) { - if ( p(*bodyIt) ) + if ( p(bodyIt.getBodyID()) ) { bodyIt = shadowStorage.remove( bodyIt ); } else diff --git a/src/pe/utility/GetBody.cpp b/src/pe/utility/GetBody.cpp index 31fc394cc8e5f3d30110fea8a342c9d639f43677..6d0b695f85915d2cae66ef9fb573420462b9a2ce 100644 --- a/src/pe/utility/GetBody.cpp +++ b/src/pe/utility/GetBody.cpp @@ -30,7 +30,7 @@ BodyID getBody(BodyStorage& globalStorage, BlockStorage& blocks, BlockDataID sto auto bodyIt = globalStorage.find(sid); if (bodyIt != globalStorage.end()) { - return *bodyIt; + return bodyIt.getBodyID(); } } @@ -44,7 +44,7 @@ BodyID getBody(BodyStorage& globalStorage, BlockStorage& blocks, BlockDataID sto auto bodyIt = localStorage.find(sid); if (bodyIt != localStorage.end()) { - return *bodyIt; + return bodyIt.getBodyID(); } } if (storageSelect & StorageSelect::SHADOW) @@ -53,7 +53,7 @@ BodyID getBody(BodyStorage& globalStorage, BlockStorage& blocks, BlockDataID sto auto bodyIt = shadowStorage.find(sid); if (bodyIt != shadowStorage.end()) { - return *bodyIt; + return bodyIt.getBodyID(); } } } diff --git a/src/pe/vtk/BodyVtkOutput.cpp b/src/pe/vtk/BodyVtkOutput.cpp index b2e154dc1248df49ad1a76db4fbf48814beb1137..6d13f3df3bc051fa85bfdb7e558d1d265f667cbd 100644 --- a/src/pe/vtk/BodyVtkOutput.cpp +++ b/src/pe/vtk/BodyVtkOutput.cpp @@ -44,14 +44,14 @@ std::vector< DefaultBodyVTKOutput::Attributes > DefaultBodyVTKOutput::getAttribu void DefaultBodyVTKOutput::configure() { bodies_.clear(); - for( auto blockIt = blockStorage_.begin(); blockIt != blockStorage_.end(); ++blockIt ) + for( const auto& block : blockStorage_ ) { - const Storage& bs = *(blockIt->getData<const Storage>( storageID_ )); + const BodyStorage& bs = (*(block.getData<const Storage>( storageID_ )))[0]; - for( auto it = bs[0].begin(); it != bs[0].end(); ++it ) + for( const auto& body : bs ) { - bodies_.push_back( *it ); + bodies_.push_back( &body ); } } } diff --git a/src/pe/vtk/EllipsoidVtkOutput.cpp b/src/pe/vtk/EllipsoidVtkOutput.cpp index 4ec85db3819595a1300a9999295d44ab91182b8d..816fb2028208731672f30f2cb8cb3e98dfadcdb0 100644 --- a/src/pe/vtk/EllipsoidVtkOutput.cpp +++ b/src/pe/vtk/EllipsoidVtkOutput.cpp @@ -47,16 +47,16 @@ void EllipsoidVtkOutput::configure() bodies_.clear(); tensorGlyphs_.clear(); - for( auto blockIt = blockStorage_.begin(); blockIt != blockStorage_.end(); ++blockIt ) + for( auto& block : blockStorage_ ) { - const Storage& bs = *(blockIt->getData<const Storage>( storageID_ )); + const BodyStorage& localStorage = (*(block.getData<const Storage>( storageID_ )))[0]; - for( auto it = bs[0].begin(); it != bs[0].end(); ++it ) + for( auto& body : localStorage ) { - if (it->getTypeID() == Ellipsoid::getStaticTypeID()) + if (body.getTypeID() == Ellipsoid::getStaticTypeID()) { - auto ellipsoid = static_cast<ConstEllipsoidID> (*it); + auto ellipsoid = static_cast<ConstEllipsoidID> (&body); bodies_.push_back(ellipsoid); // compute tensor glyph for visualization with ParaView (tensorGlyph) diff --git a/src/pe/vtk/EllipsoidVtkOutput.h b/src/pe/vtk/EllipsoidVtkOutput.h index e12f91879e6aaf0d2eb3d74f04b5d5ab3103feea..680410dcea6377fa1eadd83f64664df7f1acb4ba 100644 --- a/src/pe/vtk/EllipsoidVtkOutput.h +++ b/src/pe/vtk/EllipsoidVtkOutput.h @@ -59,7 +59,7 @@ private: ConstBlockDataID storageID_; const BlockStorage & blockStorage_; - std::vector< ConstEllipsoidID > bodies_; + std::vector< Ellipsoid const * > bodies_; std::vector< std::array<real_t,6> > tensorGlyphs_; }; diff --git a/src/pe/vtk/SphereVtkOutput.cpp b/src/pe/vtk/SphereVtkOutput.cpp index 90672a0f60d3ae642f87d21f325a5d3fcb992e9e..626685a43610f3c4cd205351f7b3835cb41a3655 100644 --- a/src/pe/vtk/SphereVtkOutput.cpp +++ b/src/pe/vtk/SphereVtkOutput.cpp @@ -49,49 +49,49 @@ std::vector< SphereVtkOutput::Attributes > SphereVtkOutput::getAttributes() cons void SphereVtkOutput::configure() { bodies_.clear(); - for( auto blockIt = blockStorage_.begin(); blockIt != blockStorage_.end(); ++blockIt ) + for( auto& block : blockStorage_ ) { - const Storage& bs = *(blockIt->getData<const Storage>( storageID_ )); + const BodyStorage& localStorage = (*(block.getData<const Storage>( storageID_ )))[0]; - for( auto it = bs[0].begin(); it != bs[0].end(); ++it ) + for( auto& body : localStorage ) { - if (it->getTypeID() == Sphere::getStaticTypeID() || it->getTypeID() == Squirmer::getStaticTypeID()) - bodies_.push_back( static_cast<ConstSphereID> (*it) ); - if (it->getTypeID() == Union<boost::tuple<Sphere> >::getStaticTypeID()) + if (body.getTypeID() == Sphere::getStaticTypeID() || body.getTypeID() == Squirmer::getStaticTypeID()) + bodies_.push_back( static_cast<Sphere const *> (&body) ); + if (body.getTypeID() == Union<boost::tuple<Sphere> >::getStaticTypeID()) { - auto un = static_cast<Union<boost::tuple<Sphere> > const * > (*it); + auto un = static_cast<Union<boost::tuple<Sphere> > const * > (&body); for( auto it2 = un->begin(); it2 != un->end(); ++it2 ) { if (it2->getTypeID() == Sphere::getStaticTypeID()) - bodies_.push_back( static_cast<ConstSphereID> (*it2) ); + bodies_.push_back( static_cast<ConstSphereID> (it2.getBodyID()) ); } } - if (it->getTypeID() == Union<boost::tuple<Squirmer> >::getStaticTypeID()) + if (body.getTypeID() == Union<boost::tuple<Squirmer> >::getStaticTypeID()) { - auto un = static_cast<Union<boost::tuple<Squirmer> > const * > (*it); + auto un = static_cast<Union<boost::tuple<Squirmer> > const * > (&body); for( auto it2 = un->begin(); it2 != un->end(); ++it2 ) { if (it2->getTypeID() == Squirmer::getStaticTypeID()) - bodies_.push_back( static_cast<ConstSphereID> (*it2) ); + bodies_.push_back( static_cast<ConstSphereID> (it2.getBodyID()) ); } } - if (it->getTypeID() == Union<boost::tuple<Sphere,Squirmer> >::getStaticTypeID()) + if (body.getTypeID() == Union<boost::tuple<Sphere,Squirmer> >::getStaticTypeID()) { - auto un = static_cast<Union<boost::tuple<Sphere,Squirmer> > const * > (*it); + auto un = static_cast<Union<boost::tuple<Sphere,Squirmer> > const * > (&body); for( auto it2 = un->begin(); it2 != un->end(); ++it2 ) { if (it2->getTypeID() == Sphere::getStaticTypeID() || it2->getTypeID() == Squirmer::getStaticTypeID()) - bodies_.push_back( static_cast<ConstSphereID> (*it2) ); + bodies_.push_back( static_cast<ConstSphereID> (it2.getBodyID()) ); } } - if (it->getTypeID() == Union<boost::tuple<Squirmer,Sphere> >::getStaticTypeID()) + if (body.getTypeID() == Union<boost::tuple<Squirmer,Sphere> >::getStaticTypeID()) { - auto un = static_cast<Union<boost::tuple<Squirmer,Sphere> > const * > (*it); + auto un = static_cast<Union<boost::tuple<Squirmer,Sphere> > const * > (&body); for( auto it2 = un->begin(); it2 != un->end(); ++it2 ) { if (it2->getTypeID() == Sphere::getStaticTypeID() || it2->getTypeID() == Squirmer::getStaticTypeID()) - bodies_.push_back( static_cast<ConstSphereID> (*it2) ); + bodies_.push_back( static_cast<ConstSphereID> (it2.getBodyID()) ); } } } diff --git a/src/pe/vtk/SphereVtkOutput.h b/src/pe/vtk/SphereVtkOutput.h index 238c1fa8e305fc95813ce798d841b7705b90f95b..1878795f32bab639db91289edf4318c57e019d5c 100644 --- a/src/pe/vtk/SphereVtkOutput.h +++ b/src/pe/vtk/SphereVtkOutput.h @@ -61,7 +61,7 @@ private: ConstBlockDataID storageID_; const BlockStorage & blockStorage_; - std::vector< ConstSphereID > bodies_; + std::vector< Sphere const * > bodies_; }; diff --git a/src/pe_coupling/discrete_particle_methods/evaluators/AddedMassForceEvaluator.h b/src/pe_coupling/discrete_particle_methods/evaluators/AddedMassForceEvaluator.h index a318686d8865509b3597d3361852c51c42c1ffcc..c452f886443049220e2529456a8fc5673175bd98 100644 --- a/src/pe_coupling/discrete_particle_methods/evaluators/AddedMassForceEvaluator.h +++ b/src/pe_coupling/discrete_particle_methods/evaluators/AddedMassForceEvaluator.h @@ -121,7 +121,7 @@ void AddedMassForceEvaluator< FlagField_T, FieldInterpolator_T, Distributor_T > for( auto bodyIt = pe::LocalBodyIterator::begin(*blockIt, bodyStorageID_); bodyIt != pe::LocalBodyIterator::end(); ++bodyIt ) { - if(!dpmBodySelectorFct_(*bodyIt)) continue; + if(!dpmBodySelectorFct_(bodyIt.getBodyID())) continue; Vector3<real_t> forceOnFluid( real_t(0) ); diff --git a/src/pe_coupling/discrete_particle_methods/evaluators/BodyVelocityTimeDerivativeEvaluator.h b/src/pe_coupling/discrete_particle_methods/evaluators/BodyVelocityTimeDerivativeEvaluator.h index 229be174ef1951b0e2601a65717457683c8d1467..7345398b7c123bd7aa83f658738a1d799dd209c5 100644 --- a/src/pe_coupling/discrete_particle_methods/evaluators/BodyVelocityTimeDerivativeEvaluator.h +++ b/src/pe_coupling/discrete_particle_methods/evaluators/BodyVelocityTimeDerivativeEvaluator.h @@ -63,7 +63,7 @@ public: { for( auto bodyIt = pe::BodyIterator::begin(*blockIt, bodyStorageID_); bodyIt != pe::BodyIterator::end(); ++bodyIt ) { - if(!dpmBodySelectorFct_(*bodyIt)) continue; + if(!dpmBodySelectorFct_(bodyIt.getBodyID())) continue; bodyVelocityMap_.insert( std::pair<walberla::id_t, Vector3< real_t > >( bodyIt->getSystemID(), bodyIt->getLinearVel() ) ); } diff --git a/src/pe_coupling/discrete_particle_methods/evaluators/InteractionForceEvaluator.h b/src/pe_coupling/discrete_particle_methods/evaluators/InteractionForceEvaluator.h index 33a2e7d76fa567bd754214a4ccba52280c31299e..17d3121898ec8e306502ffa55528c73fd9350282 100644 --- a/src/pe_coupling/discrete_particle_methods/evaluators/InteractionForceEvaluator.h +++ b/src/pe_coupling/discrete_particle_methods/evaluators/InteractionForceEvaluator.h @@ -136,7 +136,7 @@ void InteractionForceEvaluator< FlagField_T, FieldInterpolator_T, Distributor_T for( auto bodyIt = pe::LocalBodyIterator::begin(*blockIt, bodyStorageID_); bodyIt != pe::LocalBodyIterator::end(); ++bodyIt ) { - if(!dpmBodySelectorFct_(*bodyIt)) continue; + if(!dpmBodySelectorFct_(bodyIt.getBodyID())) continue; Vector3<real_t> forceOnFluid( real_t(0) ); @@ -154,7 +154,7 @@ void InteractionForceEvaluator< FlagField_T, FieldInterpolator_T, Distributor_T // evaluate drag force Vector3<real_t> bodyVelocity = bodyIt->getLinearVel(); - real_t bodyDiameter = getSphereEquivalentDiameter( *(*bodyIt) ); + real_t bodyDiameter = getSphereEquivalentDiameter( *bodyIt ); real_t bodyVolume = bodyIt->getVolume(); real_t fluidDensity( real_t(1) ); diff --git a/src/pe_coupling/discrete_particle_methods/evaluators/LiftForceEvaluator.h b/src/pe_coupling/discrete_particle_methods/evaluators/LiftForceEvaluator.h index d04ca701ca8788abc87b424b4b9b3a3328109819..de8518349033f98cfddec3c1bd1f5678b440c151 100644 --- a/src/pe_coupling/discrete_particle_methods/evaluators/LiftForceEvaluator.h +++ b/src/pe_coupling/discrete_particle_methods/evaluators/LiftForceEvaluator.h @@ -115,7 +115,7 @@ void LiftForceEvaluator< FlagField_T, FieldInterpolator_T, Distributor_T > for( auto bodyIt = pe::LocalBodyIterator::begin(*blockIt, bodyStorageID_); bodyIt != pe::LocalBodyIterator::end(); ++bodyIt ) { - if(!dpmBodySelectorFct_(*bodyIt)) continue; + if(!dpmBodySelectorFct_(bodyIt.getBodyID())) continue; Vector3<real_t> forceOnFluid( real_t(0) ); @@ -123,7 +123,7 @@ void LiftForceEvaluator< FlagField_T, FieldInterpolator_T, Distributor_T > Vector3<real_t> bodyVelocity = bodyIt->getLinearVel(); real_t fluidDensity( real_t(1) ); - real_t bodyDiameter = getSphereEquivalentDiameter( *(*bodyIt) ); + real_t bodyDiameter = getSphereEquivalentDiameter( *bodyIt ); // interpolate fluid velocity and fluid curl to body position Vector3<real_t> fluidVelocity( real_t(0) ); diff --git a/src/pe_coupling/discrete_particle_methods/evaluators/LubricationForceEvaluator.h b/src/pe_coupling/discrete_particle_methods/evaluators/LubricationForceEvaluator.h index e99d3e88f63befc5ef49a932eb395af4cad82a76..63723eaa49018c758a7052455cce4e628db3afb8 100644 --- a/src/pe_coupling/discrete_particle_methods/evaluators/LubricationForceEvaluator.h +++ b/src/pe_coupling/discrete_particle_methods/evaluators/LubricationForceEvaluator.h @@ -100,7 +100,7 @@ void LubricationForceEvaluator::operator ()() // lubrication forces for spheres if ( body1It->getTypeID() == pe::Sphere::getStaticTypeID() ) { - pe::SphereID sphereI = static_cast<pe::SphereID> ( *body1It ); + pe::SphereID sphereI = static_cast<pe::SphereID> ( body1It.getBodyID() ); auto copyBody1It = body1It; // loop over all rigid bodies after current body1 to avoid double forces @@ -109,7 +109,7 @@ void LubricationForceEvaluator::operator ()() // sphere-sphere lubrication if ( body2It->getTypeID() == pe::Sphere::getStaticTypeID() ) { - pe::SphereID sphereJ = static_cast<pe::SphereID>( *body2It ); + pe::SphereID sphereJ = static_cast<pe::SphereID>( body2It.getBodyID() ); treatLubricationSphrSphr( sphereI, sphereJ, blockIt->getAABB() ); } } @@ -121,19 +121,19 @@ void LubricationForceEvaluator::operator ()() { if ( body1It->getTypeID() == pe::Sphere::getStaticTypeID() ) { - pe::SphereID sphereI = static_cast<pe::SphereID> ( *body1It ); + pe::SphereID sphereI = static_cast<pe::SphereID> ( body1It.getBodyID() ); for (auto body2It = globalBodyStorage_->begin(); body2It != globalBodyStorage_->end(); ++body2It) { if ( body2It->getTypeID() == pe::Plane::getStaticTypeID() ) { // sphere-plane lubrication - pe::PlaneID planeJ = static_cast<pe::PlaneID>( *body2It ); + pe::PlaneID planeJ = static_cast<pe::PlaneID>( body2It.getBodyID() ); treatLubricationSphrPlane( sphereI, planeJ ); } else if ( body2It->getTypeID() == pe::Sphere::getStaticTypeID() ) { // sphere-sphere lubrication - pe::SphereID sphereJ = static_cast<pe::SphereID>( *body2It ); + pe::SphereID sphereJ = static_cast<pe::SphereID>( body2It.getBodyID() ); treatLubricationSphrSphr( sphereI, sphereJ, blockIt->getAABB() ); } } diff --git a/src/pe_coupling/discrete_particle_methods/evaluators/SolidVolumeFractionFieldEvaluator.h b/src/pe_coupling/discrete_particle_methods/evaluators/SolidVolumeFractionFieldEvaluator.h index 1c83df74afc0eba7d192454f350932307f27bef4..586b51bc25d29259c632ed1bb76dcfc4cd08c43b 100644 --- a/src/pe_coupling/discrete_particle_methods/evaluators/SolidVolumeFractionFieldEvaluator.h +++ b/src/pe_coupling/discrete_particle_methods/evaluators/SolidVolumeFractionFieldEvaluator.h @@ -89,7 +89,7 @@ public: // assign the local bodies' volume to the cell, depending on the chosen Distributor_T for( auto bodyIt = pe::LocalBodyIterator::begin(*block, bodyStorageID_); bodyIt != pe::LocalBodyIterator::end(); ++bodyIt ) { - if(!dpmBodySelectorFct_(*bodyIt)) continue; + if(!dpmBodySelectorFct_(bodyIt.getBodyID())) continue; real_t bodyVolume = bodyIt->getVolume(); const Vector3<real_t> bodyPosition = bodyIt->getPosition(); diff --git a/src/pe_coupling/discrete_particle_methods/utility/BodyVelocityInitializer.h b/src/pe_coupling/discrete_particle_methods/utility/BodyVelocityInitializer.h index 75ebeef5b370820e5f306b06c0f954c45b7dd16e..9ffbad829435d7797e2727455005d769d752344c 100644 --- a/src/pe_coupling/discrete_particle_methods/utility/BodyVelocityInitializer.h +++ b/src/pe_coupling/discrete_particle_methods/utility/BodyVelocityInitializer.h @@ -82,7 +82,7 @@ public: for( auto bodyIt = pe::LocalBodyIterator::begin(*blockIt, bodyStorageID_); bodyIt != pe::LocalBodyIterator::end(); ++bodyIt ) { - if(!dpmBodySelectorFct_(*bodyIt)) continue; + if(!dpmBodySelectorFct_(bodyIt.getBodyID())) continue; Vector3<real_t> forceOnFluid( real_t(0) ); diff --git a/src/pe_coupling/mapping/BodyMapping.h b/src/pe_coupling/mapping/BodyMapping.h index 4af2e9d3195ebaddc0ce3a6a08108c2c4d28d10d..48f05c2ee0a25b28f492ae927b052d9b9dbdc97d 100644 --- a/src/pe_coupling/mapping/BodyMapping.h +++ b/src/pe_coupling/mapping/BodyMapping.h @@ -106,14 +106,14 @@ void mapBodies( StructuredBlockStorage & blockStorage, const BlockDataID & bound for( auto bodyIt = pe::BodyIterator::begin(*blockIt, bodyStorageID); bodyIt != pe::BodyIterator::end(); ++bodyIt ) { - if( mappingBodySelectorFct(*bodyIt)) - mapBody<BoundaryHandling_T>( *bodyIt, *blockIt, blockStorage, boundaryHandlingID, obstacle ); + if( mappingBodySelectorFct(bodyIt.getBodyID())) + mapBody<BoundaryHandling_T>( bodyIt.getBodyID(), *blockIt, blockStorage, boundaryHandlingID, obstacle ); } for( auto bodyIt = globalBodyStorage.begin(); bodyIt != globalBodyStorage.end(); ++bodyIt ) { - if( mappingBodySelectorFct(*bodyIt)) - mapBody< BoundaryHandling_T >( *bodyIt, *blockIt, blockStorage, boundaryHandlingID, obstacle ); + if( mappingBodySelectorFct(bodyIt.getBodyID())) + mapBody< BoundaryHandling_T >( bodyIt.getBodyID(), *blockIt, blockStorage, boundaryHandlingID, obstacle ); } } } diff --git a/src/pe_coupling/momentum_exchange_method/BodyMapping.h b/src/pe_coupling/momentum_exchange_method/BodyMapping.h index 7651386b613b476a00d5070c1550884930a003f9..c44bc77e6a525f78c41f91127bac7def5b59096a 100644 --- a/src/pe_coupling/momentum_exchange_method/BodyMapping.h +++ b/src/pe_coupling/momentum_exchange_method/BodyMapping.h @@ -102,13 +102,13 @@ public: for( auto bodyIt = pe::BodyIterator::begin(*block, bodyStorageID_); bodyIt != pe::BodyIterator::end(); ++bodyIt ) { - if( mappingBodySelectorFct_(*bodyIt) ) - mapBodyAndUpdateMapping(*bodyIt, block, boundaryHandling, flagField , bodyField, obstacle, formerObstacle, dx, dy, dz); + if( mappingBodySelectorFct_(bodyIt.getBodyID()) ) + mapBodyAndUpdateMapping(bodyIt.getBodyID(), block, boundaryHandling, flagField , bodyField, obstacle, formerObstacle, dx, dy, dz); } for( auto bodyIt = globalBodyStorage_->begin(); bodyIt != globalBodyStorage_->end(); ++bodyIt) { - if( mappingBodySelectorFct_(*bodyIt)) - mapBodyAndUpdateMapping(*bodyIt, block, boundaryHandling, flagField , bodyField, obstacle, formerObstacle, dx, dy, dz); + if( mappingBodySelectorFct_(bodyIt.getBodyID())) + mapBodyAndUpdateMapping(bodyIt.getBodyID(), block, boundaryHandling, flagField , bodyField, obstacle, formerObstacle, dx, dy, dz); } } @@ -273,13 +273,13 @@ void mapMovingBodies( StructuredBlockStorage & blockStorage, const BlockDataID & { for (auto bodyIt = pe::BodyIterator::begin(*blockIt, bodyStorageID); bodyIt != pe::BodyIterator::end(); ++bodyIt) { - if( mappingBodySelectorFct(*bodyIt)) - mapMovingBody< BoundaryHandling_T >( *bodyIt, *blockIt, blockStorage, boundaryHandlingID, bodyFieldID, obstacle ); + if( mappingBodySelectorFct(bodyIt.getBodyID())) + mapMovingBody< BoundaryHandling_T >( bodyIt.getBodyID(), *blockIt, blockStorage, boundaryHandlingID, bodyFieldID, obstacle ); } for( auto bodyIt = globalBodyStorage.begin(); bodyIt != globalBodyStorage.end(); ++bodyIt) { - if( mappingBodySelectorFct(*bodyIt)) - mapMovingBody< BoundaryHandling_T >( *bodyIt, *blockIt, blockStorage, boundaryHandlingID, bodyFieldID, obstacle ); + if( mappingBodySelectorFct(bodyIt.getBodyID())) + mapMovingBody< BoundaryHandling_T >( bodyIt.getBodyID(), *blockIt, blockStorage, boundaryHandlingID, bodyFieldID, obstacle ); } } } diff --git a/src/pe_coupling/momentum_exchange_method/boundary/CurvedLinear.h b/src/pe_coupling/momentum_exchange_method/boundary/CurvedLinear.h index b23b33c83ef134373c739a7234c75fbce4073363..05fee404db1b0cb47a1d1a28216ee7de481dca1d 100644 --- a/src/pe_coupling/momentum_exchange_method/boundary/CurvedLinear.h +++ b/src/pe_coupling/momentum_exchange_method/boundary/CurvedLinear.h @@ -71,6 +71,12 @@ class CurvedLinear : public Boundary< typename FlagField_T::flag_t > public: + static shared_ptr<BoundaryConfiguration> createConfiguration( const Config::BlockHandle& ) + { + WALBERLA_ABORT( "A CurvedLinear boundary cannot be created from a config file" ); + return make_shared<BoundaryConfiguration>(); + } + inline CurvedLinear( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField_T * const pdfField, const FlagField_T * const flagField, BodyField_T * const bodyField, const flag_t domain, const StructuredBlockStorage & blockStorage, const IBlock & block ); diff --git a/src/pe_coupling/momentum_exchange_method/boundary/CurvedQuadratic.h b/src/pe_coupling/momentum_exchange_method/boundary/CurvedQuadratic.h index fa0b22852f6997a4ed9a4e7801ccc48222405c98..ea6fe8b665bcc9dfb7aab137774cfee05680a545 100644 --- a/src/pe_coupling/momentum_exchange_method/boundary/CurvedQuadratic.h +++ b/src/pe_coupling/momentum_exchange_method/boundary/CurvedQuadratic.h @@ -81,6 +81,12 @@ class CurvedQuadratic : public Boundary< typename FlagField_T::flag_t > public: + static shared_ptr<BoundaryConfiguration> createConfiguration( const Config::BlockHandle& ) + { + WALBERLA_ABORT( "A CurvedQuadratic boundary cannot be created from a config file" ); + return make_shared<BoundaryConfiguration>(); + } + inline CurvedQuadratic( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField_T * const pdfField, const FlagField_T * const flagField, BodyField_T * const bodyField, const flag_t domain, const StructuredBlockStorage & blockStorage, const IBlock & block, PDFField_T * const pdfFieldPreCollision ); diff --git a/src/pe_coupling/momentum_exchange_method/boundary/SimpleBB.h b/src/pe_coupling/momentum_exchange_method/boundary/SimpleBB.h index cfe78d575837e17f1f6adc63179bf48a5a3ab93b..0d7af9d9ae3f9817147bbfdf4ed294c8f85ac848 100644 --- a/src/pe_coupling/momentum_exchange_method/boundary/SimpleBB.h +++ b/src/pe_coupling/momentum_exchange_method/boundary/SimpleBB.h @@ -67,6 +67,12 @@ class SimpleBB : public Boundary< typename FlagField_T::flag_t > public: + static shared_ptr<BoundaryConfiguration> createConfiguration( const Config::BlockHandle& ) + { + WALBERLA_ABORT( "A SimpleBB boundary cannot be created from a config file" ); + return make_shared<BoundaryConfiguration>(); + } + inline SimpleBB( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField_T * const pdfField, const FlagField_T * const flagField, BodyField * const bodyField, const flag_t domain, const StructuredBlockStorage & blockStorage, const IBlock & block ); diff --git a/src/pe_coupling/momentum_exchange_method/restoration/PDFReconstruction.h b/src/pe_coupling/momentum_exchange_method/restoration/PDFReconstruction.h index d21808bb3cc8bae4084ea24bff84b6051dd30253..808fc089f1038092a5a54460f5e6bee46eea3e12 100644 --- a/src/pe_coupling/momentum_exchange_method/restoration/PDFReconstruction.h +++ b/src/pe_coupling/momentum_exchange_method/restoration/PDFReconstruction.h @@ -163,18 +163,18 @@ void PDFReconstruction< LatticeModel_T, BoundaryHandling_T, Reconstructer_T > for( auto bodyIt = pe::BodyIterator::begin(*block, bodyStorageID_); bodyIt != pe::BodyIterator::end(); ++bodyIt ) { - if( !movingBodySelectorFct_(*bodyIt) ) + if( !movingBodySelectorFct_(bodyIt.getBodyID()) ) continue; - CellInterval cellBB = getCellBB( *bodyIt, *block, *blockStorage_, numberOfGhostLayersToInclude ); + CellInterval cellBB = getCellBB( bodyIt.getBodyID(), *block, *blockStorage_, numberOfGhostLayersToInclude ); reconstructPDFsInCells(cellBB, block, flagField, formerObstacle ); } for( auto bodyIt = globalBodyStorage_->begin(); bodyIt != globalBodyStorage_->end(); ++bodyIt ) { - if( !movingBodySelectorFct_(*bodyIt) ) + if( !movingBodySelectorFct_(bodyIt.getBodyID()) ) continue; - CellInterval cellBB = getCellBB( *bodyIt, *block, *blockStorage_, numberOfGhostLayersToInclude ); + CellInterval cellBB = getCellBB( bodyIt.getBodyID(), *block, *blockStorage_, numberOfGhostLayersToInclude ); reconstructPDFsInCells(cellBB, block, flagField, formerObstacle ); } } @@ -191,18 +191,18 @@ void PDFReconstruction< LatticeModel_T, BoundaryHandling_T, Reconstructer_T > for( auto bodyIt = pe::BodyIterator::begin(*block, bodyStorageID_); bodyIt != pe::BodyIterator::end(); ++bodyIt ) { - if( !movingBodySelectorFct_(*bodyIt) ) + if( !movingBodySelectorFct_(bodyIt.getBodyID()) ) continue; - CellInterval cellBB = getCellBB( *bodyIt, *block, *blockStorage_, numberOfGhostLayersToInclude ); + CellInterval cellBB = getCellBB( bodyIt.getBodyID(), *block, *blockStorage_, numberOfGhostLayersToInclude ); updateFlags(cellBB, boundaryHandling, flagField, bodyField, formerObstacle, fluid); } for( auto bodyIt = globalBodyStorage_->begin(); bodyIt != globalBodyStorage_->end(); ++bodyIt ) { - if( !movingBodySelectorFct_(*bodyIt) ) + if( !movingBodySelectorFct_(bodyIt.getBodyID()) ) continue; - CellInterval cellBB = getCellBB( *bodyIt, *block, *blockStorage_, numberOfGhostLayersToInclude ); + CellInterval cellBB = getCellBB( bodyIt.getBodyID(), *block, *blockStorage_, numberOfGhostLayersToInclude ); updateFlags(cellBB, boundaryHandling, flagField, bodyField, formerObstacle, fluid); } } diff --git a/src/pe_coupling/partially_saturated_cells_method/BodyAndVolumeFractionMapping.h b/src/pe_coupling/partially_saturated_cells_method/BodyAndVolumeFractionMapping.h index 9f28d42e6bd41f2226766c3e6b88bb8ad0b350ec..1a387105bd936ff7437c0d4b6cd102aecda40d0b 100644 --- a/src/pe_coupling/partially_saturated_cells_method/BodyAndVolumeFractionMapping.h +++ b/src/pe_coupling/partially_saturated_cells_method/BodyAndVolumeFractionMapping.h @@ -178,18 +178,18 @@ void BodyAndVolumeFractionMapping::initialize() for( auto bodyIt = pe::BodyIterator::begin( *blockIt, bodyStorageID_); bodyIt != pe::BodyIterator::end(); ++bodyIt ) { - if( mappingBodySelectorFct_(*bodyIt) ) + if( mappingBodySelectorFct_(bodyIt.getBodyID()) ) { - mapPSMBodyAndVolumeFraction( *bodyIt, *blockIt, *blockStorage_, bodyAndVolumeFractionFieldID_ ); + mapPSMBodyAndVolumeFraction( bodyIt.getBodyID(), *blockIt, *blockStorage_, bodyAndVolumeFractionFieldID_ ); lastUpdatedPositionMap_.insert( std::pair< walberla::id_t, Vector3< real_t > >( bodyIt->getSystemID(), bodyIt->getPosition() ) ); } } for( auto bodyIt = globalBodyStorage_->begin(); bodyIt != globalBodyStorage_->end(); ++bodyIt ) { - if( mappingBodySelectorFct_(*bodyIt) ) + if( mappingBodySelectorFct_(bodyIt.getBodyID()) ) { - mapPSMBodyAndVolumeFraction(*bodyIt, *blockIt, *blockStorage_, bodyAndVolumeFractionFieldID_); + mapPSMBodyAndVolumeFraction(bodyIt.getBodyID(), *blockIt, *blockStorage_, bodyAndVolumeFractionFieldID_); lastUpdatedPositionMap_.insert( std::pair< walberla::id_t, Vector3< real_t > >( bodyIt->getSystemID(), bodyIt->getPosition() ) ); } } @@ -207,17 +207,17 @@ void BodyAndVolumeFractionMapping::update() for( auto bodyIt = pe::BodyIterator::begin( *blockIt, bodyStorageID_); bodyIt != pe::BodyIterator::end(); ++bodyIt ) { - if( mappingBodySelectorFct_(*bodyIt) ) + if( mappingBodySelectorFct_(bodyIt.getBodyID()) ) { - updatePSMBodyAndVolumeFraction(*bodyIt, *blockIt, bodyAndVolumeFractionField, tempLastUpdatedPositionMap); + updatePSMBodyAndVolumeFraction(bodyIt.getBodyID(), *blockIt, bodyAndVolumeFractionField, tempLastUpdatedPositionMap); } } for( auto bodyIt = globalBodyStorage_->begin(); bodyIt != globalBodyStorage_->end(); ++bodyIt ) { - if( mappingBodySelectorFct_(*bodyIt) ) + if( mappingBodySelectorFct_(bodyIt.getBodyID()) ) { - updatePSMBodyAndVolumeFraction(*bodyIt, *blockIt, bodyAndVolumeFractionField, tempLastUpdatedPositionMap); + updatePSMBodyAndVolumeFraction(bodyIt.getBodyID(), *blockIt, bodyAndVolumeFractionField, tempLastUpdatedPositionMap); } } diff --git a/src/pe_coupling/utility/LubricationCorrection.h b/src/pe_coupling/utility/LubricationCorrection.h index c318c66c6e42b3a3bdb3cafc50854b8f82c60569..4a5afa830d09352ff53ae87c69e88c96c7533eae 100644 --- a/src/pe_coupling/utility/LubricationCorrection.h +++ b/src/pe_coupling/utility/LubricationCorrection.h @@ -89,7 +89,7 @@ void LubricationCorrection::operator ()() // lubrication forces for spheres if ( body1It->getTypeID() == pe::Sphere::getStaticTypeID() ) { - pe::SphereID sphereI = static_cast<pe::SphereID> ( *body1It ); + pe::SphereID sphereI = static_cast<pe::SphereID> ( body1It.getBodyID() ); auto copyBody1It = body1It; // loop over all rigid bodies after current body1 to avoid double forces @@ -98,7 +98,7 @@ void LubricationCorrection::operator ()() // sphere-sphere lubrication if ( body2It->getTypeID() == pe::Sphere::getStaticTypeID() ) { - pe::SphereID sphereJ = static_cast<pe::SphereID>( *body2It ); + pe::SphereID sphereJ = static_cast<pe::SphereID>( body2It.getBodyID() ); treatLubricationSphrSphr( sphereI, sphereJ, blockIt->getAABB() ); } } @@ -110,19 +110,19 @@ void LubricationCorrection::operator ()() { if ( body1It->getTypeID() == pe::Sphere::getStaticTypeID() ) { - pe::SphereID sphereI = static_cast<pe::SphereID> ( *body1It ); + pe::SphereID sphereI = static_cast<pe::SphereID> ( body1It.getBodyID() ); for (auto body2It = globalBodyStorage_->begin(); body2It != globalBodyStorage_->end(); ++body2It) { if ( body2It->getTypeID() == pe::Plane::getStaticTypeID() ) { // sphere-plane lubrication - pe::PlaneID planeJ = static_cast<pe::PlaneID>( *body2It ); + pe::PlaneID planeJ = static_cast<pe::PlaneID>( body2It.getBodyID() ); treatLubricationSphrPlane( sphereI, planeJ ); } else if ( body2It->getTypeID() == pe::Sphere::getStaticTypeID() ) { // sphere-sphere lubrication - pe::SphereID sphereJ = static_cast<pe::SphereID>( *body2It ); + pe::SphereID sphereJ = static_cast<pe::SphereID>( body2It.getBodyID() ); treatLubricationSphrSphr( sphereI, sphereJ, blockIt->getAABB() ); } } diff --git a/src/postprocessing/sqlite/SQLite.cpp b/src/postprocessing/sqlite/SQLite.cpp index 049b5ed8b59144abecadc77620e8a097376d0f66..e83aa46e18a0627452791efb16568d07e07efcb6 100644 --- a/src/postprocessing/sqlite/SQLite.cpp +++ b/src/postprocessing/sqlite/SQLite.cpp @@ -34,43 +34,43 @@ namespace walberla { namespace postprocessing { - SQLiteDB::SQLiteDB( const string & dbFile, const int busyTimeout ) - : valid_(true), dbHandle_(NULL), file_( dbFile ) - { - static const char * CREATE_RUN_TABLE = - "CREATE TABLE IF NOT EXISTS runs (" - " runId INTEGER PRIMARY KEY, " - " timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, " - " uuid STRING );" ; - - // Create tables if it does not exist - int retVal = sqlite3_open( file_.c_str(), &dbHandle_ ); - if ( retVal != SQLITE_OK ) { - WALBERLA_LOG_WARNING( "Failed to open sqlite3 file." << dbFile ); - valid_ = false; - return; - } +SQLiteDB::SQLiteDB( const string & dbFile, const int busyTimeout ) + : valid_(true), dbHandle_(NULL), file_( dbFile ) +{ + static const char * CREATE_RUN_TABLE = + "CREATE TABLE IF NOT EXISTS runs (" + " runId INTEGER PRIMARY KEY, " + " timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, " + " uuid STRING );" ; + + // Create tables if it does not exist + int retVal = sqlite3_open( file_.c_str(), &dbHandle_ ); + if ( retVal != SQLITE_OK ) { + WALBERLA_LOG_WARNING( "Failed to open sqlite3 file." << dbFile ); + valid_ = false; + return; + } - sqlite3_busy_timeout( dbHandle_, busyTimeout*1000 ); - sqlite3_exec( dbHandle_, "PRAGMA foreign_keys = ON;",0,0,0 ); - sqlite3_exec( dbHandle_, CREATE_RUN_TABLE, 0,0,0); + sqlite3_busy_timeout( dbHandle_, busyTimeout*1000 ); + sqlite3_exec( dbHandle_, "PRAGMA foreign_keys = ON;",0,0,0 ); + sqlite3_exec( dbHandle_, CREATE_RUN_TABLE, 0,0,0); - static const char* UPDATE_RUN_TABLE_CMD = "ALTER TABLE runs ADD COLUMN uuid STRING;"; - sqlite3_exec( dbHandle_, UPDATE_RUN_TABLE_CMD, 0, 0, 0 ); + static const char* UPDATE_RUN_TABLE_CMD = "ALTER TABLE runs ADD COLUMN uuid STRING;"; + sqlite3_exec( dbHandle_, UPDATE_RUN_TABLE_CMD, 0, 0, 0 ); - } +} - SQLiteDB::~SQLiteDB () - { - if ( valid_ ) - sqlite3_close( dbHandle_ ); - } +SQLiteDB::~SQLiteDB () +{ + if ( valid_ ) + sqlite3_close( dbHandle_ ); +} - //******************************************************************************************************************* - /*! Store information about a simulation run into a Sqlite3 Database +//******************************************************************************************************************* +/*! Store information about a simulation run into a Sqlite3 Database * * The generated database is called "runs". The columns of the table are the keys of the given maps. * If a column does not yet exist, it is appended to the database. The entries that have no value in this column @@ -80,152 +80,152 @@ namespace postprocessing { * \param *Properties Map of column names to value * \returns The primary key of the inserted data set. */ - //******************************************************************************************************************* - template<typename IntType> - uint_t storeRunImpl( sqlite3 * dbHandle, std::string & filename, - const map<string, IntType> & integerProperties, - const map<string, string > & stringProperties, - const map<string, double > & realProperties ) +//******************************************************************************************************************* +template<typename IntType> +uint_t storeRunImpl( sqlite3 * dbHandle, std::string & filename, + const map<string, IntType> & integerProperties, + const map<string, string > & stringProperties, + const map<string, double > & realProperties ) +{ + WALBERLA_ASSERT_NOT_NULLPTR( dbHandle ); + + sqlite3_exec( dbHandle, "BEGIN;",0,0,0 ); + + string insertRunCommand = "INSERT INTO runs (timestamp, uuid "; + std::stringstream values; + auto uuid = boost::uuids::random_generator()(); + values << " VALUES ( CURRENT_TIMESTAMP, \"" << uuid << "\" "; + // Add columns for integer properties + for ( auto i = integerProperties.begin(); i != integerProperties.end(); ++i ) { - WALBERLA_ASSERT_NOT_NULLPTR( dbHandle ); + insertRunCommand += "," + i->first; + values << ", " << i->second; + string command = "ALTER TABLE runs ADD COLUMN " + i->first + " INTEGER "; + sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already) + } - sqlite3_exec( dbHandle, "BEGIN;",0,0,0 ); + // Add columns for string properties + for ( auto i = stringProperties.begin(); i != stringProperties.end(); ++i ) + { + insertRunCommand += "," + i->first; + values << ", " << "\"" << i->second << "\""; + string command = "ALTER TABLE runs ADD COLUMN " + i->first + " TEXT "; + sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already) - string insertRunCommand = "INSERT INTO runs (timestamp, uuid "; - std::stringstream values; - auto uuid = boost::uuids::random_generator()(); - values << " VALUES ( CURRENT_TIMESTAMP, \"" << uuid << "\" "; - // Add columns for integer properties - for ( auto i = integerProperties.begin(); i != integerProperties.end(); ++i ) - { - insertRunCommand += "," + i->first; - values << ", " << i->second; - string command = "ALTER TABLE runs ADD COLUMN " + i->first + " INTEGER "; - sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already) - } + } - // Add columns for string properties - for ( auto i = stringProperties.begin(); i != stringProperties.end(); ++i ) + // Add columns for real_t properties + for ( auto i = realProperties.begin(); i != realProperties.end(); ++i ) + { + if( math::finite( i->second ) ) { insertRunCommand += "," + i->first; - values << ", " << "\"" << i->second << "\""; - string command = "ALTER TABLE runs ADD COLUMN " + i->first + " TEXT "; - sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already) - + values << ", " << i->second; + string command = "ALTER TABLE runs ADD COLUMN " + i->first + " DOUBLE "; + sqlite3_exec( dbHandle, command.c_str(), 0, 0, 0 ); // ignore errors (column can exist already) } - - // Add columns for real_t properties - for ( auto i = realProperties.begin(); i != realProperties.end(); ++i ) - { - if( math::finite( i->second ) ) - { - insertRunCommand += "," + i->first; - values << ", " << i->second; - string command = "ALTER TABLE runs ADD COLUMN " + i->first + " DOUBLE "; - sqlite3_exec( dbHandle, command.c_str(), 0, 0, 0 ); // ignore errors (column can exist already) - } - else - { - WALBERLA_LOG_WARNING( "Skipping column \"" << i->first << "\" while inserting a row into the run table of the " - "sqlite3 database \"" << filename << "\" due to non-finite value \"" << i->second << "\"." ); - } - } - - // Add columns for global state selectors - for( auto i = uid::globalState().begin(); i != uid::globalState().end(); ++i ) + else { - insertRunCommand += "," + i->getIdentifier(); - values << " ,1"; - // no boolean in sqlite3, use integer instead - string command = "ALTER TABLE runs ADD COLUMN " + i->getIdentifier() + " INTEGER "; - sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already) + WALBERLA_LOG_WARNING( "Skipping column \"" << i->first << "\" while inserting a row into the run table of the " + "sqlite3 database \"" << filename << "\" due to non-finite value \"" << i->second << "\"." ); } + } - insertRunCommand += " ) "; - values << "); "; - insertRunCommand += values.str(); - - int ret = sqlite3_exec ( dbHandle, insertRunCommand.c_str(), 0, 0, 0 ); - if ( ret != SQLITE_OK) { - WALBERLA_LOG_WARNING( "Failed to insert a row into run table of sqlite3 database: " << sqlite3_errmsg(dbHandle) << "\n sql command: " << insertRunCommand.c_str() ); - } - uint_t generatedPrimaryKey = uint_c ( sqlite3_last_insert_rowid( dbHandle ) ); + // Add columns for global state selectors + for( auto i = uid::globalState().begin(); i != uid::globalState().end(); ++i ) + { + insertRunCommand += "," + i->getIdentifier(); + values << " ,1"; + // no boolean in sqlite3, use integer instead + string command = "ALTER TABLE runs ADD COLUMN " + i->getIdentifier() + " INTEGER "; + sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already) + } - sqlite3_exec( dbHandle, "END TRANSACTION;",0,0,0 ); + insertRunCommand += " ) "; + values << "); "; + insertRunCommand += values.str(); - return generatedPrimaryKey; + int ret = sqlite3_exec ( dbHandle, insertRunCommand.c_str(), 0, 0, 0 ); + if ( ret != SQLITE_OK) { + WALBERLA_LOG_WARNING( "Failed to insert a row into run table of sqlite3 database: " << sqlite3_errmsg(dbHandle) << "\n sql command: " << insertRunCommand.c_str() ); } + uint_t generatedPrimaryKey = uint_c ( sqlite3_last_insert_rowid( dbHandle ) ); + + sqlite3_exec( dbHandle, "END TRANSACTION;",0,0,0 ); - //******************************************************************************************************************* - /*! Stores information in another table, referencing the "run" table + return generatedPrimaryKey; +} + +//******************************************************************************************************************* +/*! Stores information in another table, referencing the "run" table * * \param runId result of storeRun() member function, primary key of the run to store information for * \param tableName name of the table where the information is stored in * is created if it does not yet exist * \param *Properties Map of column names to value */ - //******************************************************************************************************************* - template<typename IntType> - void storeAdditionalRunInfoImpl( sqlite3 * dbHandle, - uint_t runId, const std::string & tableName, - const map<string, IntType> & integerProperties, - const map<string, string > & stringProperties , - const map<string, double > & realProperties ) +//******************************************************************************************************************* +template<typename IntType> +void storeAdditionalRunInfoImpl( sqlite3 * dbHandle, + uint_t runId, const std::string & tableName, + const map<string, IntType> & integerProperties, + const map<string, string > & stringProperties , + const map<string, double > & realProperties ) +{ + sqlite3_exec( dbHandle, "BEGIN;",0,0,0 ); + std::string CREATE_TABLE = + "CREATE TABLE IF NOT EXISTS " + tableName + + " (runId INTEGER, " + " FOREIGN KEY (runId) REFERENCES runs(runId) " + " );" ; + + sqlite3_exec( dbHandle, CREATE_TABLE.c_str(), 0,0,0); + + string insertRunCommand = "INSERT INTO " + tableName + "( runId"; + std::stringstream values; + values << " VALUES ( " << runId; + // Add columns for integer properties + for ( auto i = integerProperties.begin(); i != integerProperties.end(); ++i ) { - sqlite3_exec( dbHandle, "BEGIN;",0,0,0 ); - std::string CREATE_TABLE = - "CREATE TABLE IF NOT EXISTS " + tableName + - " (runId INTEGER, " - " FOREIGN KEY (runId) REFERENCES runs(runId) " - " );" ; - - sqlite3_exec( dbHandle, CREATE_TABLE.c_str(), 0,0,0); - - string insertRunCommand = "INSERT INTO " + tableName + "( runId"; - std::stringstream values; - values << " VALUES ( " << runId; - // Add columns for integer properties - for ( auto i = integerProperties.begin(); i != integerProperties.end(); ++i ) - { - insertRunCommand += "," + i->first; - values << ", " << i->second; - string command = "ALTER TABLE " + tableName + " ADD COLUMN " + i->first + " INTEGER "; - sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already) - } + insertRunCommand += "," + i->first; + values << ", " << i->second; + string command = "ALTER TABLE " + tableName + " ADD COLUMN " + i->first + " INTEGER "; + sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already) + } - // Add columns for string properties - for ( auto i = stringProperties.begin(); i != stringProperties.end(); ++i ) - { - insertRunCommand += "," + i->first; - values << ", " << "\"" << i->second << "\""; - string command = "ALTER TABLE " + tableName + " ADD COLUMN " + i->first + " TEXT "; - sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already) + // Add columns for string properties + for ( auto i = stringProperties.begin(); i != stringProperties.end(); ++i ) + { + insertRunCommand += "," + i->first; + values << ", " << "\"" << i->second << "\""; + string command = "ALTER TABLE " + tableName + " ADD COLUMN " + i->first + " TEXT "; + sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already) - } + } - // Add columns for real_t properties - for ( auto i = realProperties.begin(); i != realProperties.end(); ++i ) - { - insertRunCommand += "," + i->first; - values << ", " << i->second ; - string command = "ALTER TABLE " + tableName + " ADD COLUMN " + i->first + " DOUBLE "; - sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already) - } - - insertRunCommand += " ) "; - values << "); "; - insertRunCommand += values.str(); - - int ret = sqlite3_exec ( dbHandle, insertRunCommand.c_str(), 0, 0, 0 ); - if ( ret != SQLITE_OK) { - WALBERLA_LOG_WARNING( "Failed to insert a row into run table of sqlite3 database: " << sqlite3_errmsg(dbHandle) << "\n sql command: " << insertRunCommand.c_str() ); - } - sqlite3_exec( dbHandle, "END TRANSACTION;",0,0,0 ); + // Add columns for real_t properties + for ( auto i = realProperties.begin(); i != realProperties.end(); ++i ) + { + insertRunCommand += "," + i->first; + values << ", " << i->second ; + string command = "ALTER TABLE " + tableName + " ADD COLUMN " + i->first + " DOUBLE "; + sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already) + } + + insertRunCommand += " ) "; + values << "); "; + insertRunCommand += values.str(); + + int ret = sqlite3_exec ( dbHandle, insertRunCommand.c_str(), 0, 0, 0 ); + if ( ret != SQLITE_OK) { + WALBERLA_LOG_WARNING( "Failed to insert a row into run table of sqlite3 database: " << sqlite3_errmsg(dbHandle) << "\n sql command: " << insertRunCommand.c_str() ); } + sqlite3_exec( dbHandle, "END TRANSACTION;",0,0,0 ); +} - //******************************************************************************************************************* - /*! Store information about a simulation run into a Sqlite3 Database +//******************************************************************************************************************* +/*! Store information about a simulation run into a Sqlite3 Database * * The generated database is called "runs". The columns of the table are the keys of the given maps. * If a column does not yet exist, it is appended to the database. The entries that have no value in this column @@ -235,52 +235,52 @@ namespace postprocessing { * \param *Properties Map of column names to value * \returns The primary key of the inserted data set. */ - //******************************************************************************************************************* - uint_t SQLiteDB::storeRun( const map<string, int> & integerProperties, - const map<string, string > & stringProperties, - const map<string, double > & realProperties ) - { - return storeRunImpl(dbHandle_, file_, integerProperties, stringProperties, realProperties); - } - /// \see storeRun - uint_t SQLiteDB::storeRun( const map<string, int64_t> & integerProperties, - const map<string, string > & stringProperties, - const map<string, double > & realProperties ) - { - return storeRunImpl(dbHandle_, file_, integerProperties, stringProperties, realProperties); - } - - - - //******************************************************************************************************************* - /*! Stores information in another table, referencing the "run" table +//******************************************************************************************************************* +uint_t SQLiteDB::storeRun( const map<string, int> & integerProperties, + const map<string, string > & stringProperties, + const map<string, double > & realProperties ) +{ + return storeRunImpl(dbHandle_, file_, integerProperties, stringProperties, realProperties); +} +/// \see storeRun +uint_t SQLiteDB::storeRun( const map<string, int64_t> & integerProperties, + const map<string, string > & stringProperties, + const map<string, double > & realProperties ) +{ + return storeRunImpl(dbHandle_, file_, integerProperties, stringProperties, realProperties); +} + + + +//******************************************************************************************************************* +/*! Stores information in another table, referencing the "run" table * * \param runId result of storeRun() member function, primary key of the run to store information for * \param tableName name of the table where the information is stored in * is created if it does not yet exist * \param *Properties Map of column names to value */ - //******************************************************************************************************************* - void SQLiteDB::storeAdditionalRunInfo( uint_t runId, const std::string & tableName, - const map<string, int> & integerProperties, - const map<string, string > & stringProperties , - const map<string, double > & realProperties ) - { - return storeAdditionalRunInfoImpl( dbHandle_, runId, tableName, integerProperties, stringProperties, realProperties); - } - /// \see storeAdditionalRunInfo - void SQLiteDB::storeAdditionalRunInfo( uint_t runId, const std::string & tableName, - const map<string, int64_t> & integerProperties, - const map<string, string > & stringProperties , - const map<string, double > & realProperties ) - { - return storeAdditionalRunInfoImpl( dbHandle_, runId, tableName, integerProperties, stringProperties, realProperties); - } - - - - //******************************************************************************************************************* - /*! Stores a TimingPool in a Sqlite3 Database, and links it to a run +//******************************************************************************************************************* +void SQLiteDB::storeAdditionalRunInfo( uint_t runId, const std::string & tableName, + const map<string, int> & integerProperties, + const map<string, string > & stringProperties , + const map<string, double > & realProperties ) +{ + return storeAdditionalRunInfoImpl( dbHandle_, runId, tableName, integerProperties, stringProperties, realProperties); +} +/// \see storeAdditionalRunInfo +void SQLiteDB::storeAdditionalRunInfo( uint_t runId, const std::string & tableName, + const map<string, int64_t> & integerProperties, + const map<string, string > & stringProperties , + const map<string, double > & realProperties ) +{ + return storeAdditionalRunInfoImpl( dbHandle_, runId, tableName, integerProperties, stringProperties, realProperties); +} + + + +//******************************************************************************************************************* +/*! Stores a TimingPool in a Sqlite3 Database, and links it to a run * * The generated table is called "timingPools" * @@ -288,16 +288,16 @@ namespace postprocessing { * \param tp the TimingPool to store * \param name name of the timing pool ( as written to database column ) */ - //******************************************************************************************************************* - void SQLiteDB::storeTimingPool ( uint_t runId, - const WcTimingPool & tp, - const std::string & timingPoolName ) - { - sqlite3_exec( dbHandle_, "BEGIN;",0,0,0 ); +//******************************************************************************************************************* +void SQLiteDB::storeTimingPool ( uint_t runId, + const WcTimingPool & tp, + const std::string & timingPoolName ) +{ + sqlite3_exec( dbHandle_, "BEGIN;",0,0,0 ); - assert ( timingPoolName.length() > 0 && timingPoolName.length() < 255 ); + assert ( timingPoolName.length() > 0 && timingPoolName.length() < 255 ); - static const char * CREATE_TIMINGPOOL_TABLE = + static const char * CREATE_TIMINGPOOL_TABLE = "CREATE TABLE IF NOT EXISTS timingPool (" " runId INTEGER, " " name VARCHAR(255)," @@ -312,47 +312,47 @@ namespace postprocessing { " );" ; - static const char * INSERT_STATEMENT = - " INSERT INTO timingPool (runId,name,sweep,average,min,max,count,variance,percentage) " - " VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ? )"; + static const char * INSERT_STATEMENT = + " INSERT INTO timingPool (runId,name,sweep,average,min,max,count,variance,percentage) " + " VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ? )"; - sqlite3_exec( dbHandle_, CREATE_TIMINGPOOL_TABLE, 0,0,0 ); + sqlite3_exec( dbHandle_, CREATE_TIMINGPOOL_TABLE, 0,0,0 ); - sqlite3_stmt *stmt = NULL; - auto retVal = sqlite3_prepare_v2(dbHandle_, INSERT_STATEMENT, -1, &stmt, 0 ); - if ( retVal != SQLITE_OK ) { - WALBERLA_LOG_WARNING( "Failed to prepare SQL Insert statement." << file_ ); - return; - } + sqlite3_stmt *stmt = NULL; + auto retVal = sqlite3_prepare_v2(dbHandle_, INSERT_STATEMENT, -1, &stmt, 0 ); + if ( retVal != SQLITE_OK ) { + WALBERLA_LOG_WARNING( "Failed to prepare SQL Insert statement." << file_ ); + return; + } - double totalTime = 0; - for ( auto i = tp.begin(); i != tp.end(); ++i ) - totalTime += i->second.total(); + double totalTime = 0; + for ( auto i = tp.begin(); i != tp.end(); ++i ) + totalTime += i->second.total(); - for ( auto i = tp.begin(); i != tp.end(); ++i ) - { - sqlite3_bind_int64 ( stmt, 1, int64_c(runId) ); - sqlite3_bind_text ( stmt, 2, timingPoolName.c_str() , -1, SQLITE_STATIC ); - sqlite3_bind_text ( stmt, 3, i->first.c_str() , -1, SQLITE_STATIC ); - sqlite3_bind_double( stmt, 4, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.average() ) ) ); - sqlite3_bind_double( stmt, 5, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.min() ) ) ); - sqlite3_bind_double( stmt, 6, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.max() ) ) ); - sqlite3_bind_int64 ( stmt, 7, int64_c ( i->second.getCounter() )); - sqlite3_bind_double( stmt, 8, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.variance() ) ) ); - sqlite3_bind_double( stmt, 9, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.total() / totalTime ) ) ); - - sqlite3_step ( stmt ); // execute statement - sqlite3_reset ( stmt ); // undo binding - } - sqlite3_exec( dbHandle_, "END TRANSACTION;",0,0,0 ); + for ( auto i = tp.begin(); i != tp.end(); ++i ) + { + sqlite3_bind_int64 ( stmt, 1, int64_c(runId) ); + sqlite3_bind_text ( stmt, 2, timingPoolName.c_str() , -1, SQLITE_STATIC ); + sqlite3_bind_text ( stmt, 3, i->first.c_str() , -1, SQLITE_STATIC ); + sqlite3_bind_double( stmt, 4, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.average() ) ) ); + sqlite3_bind_double( stmt, 5, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.min() ) ) ); + sqlite3_bind_double( stmt, 6, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.max() ) ) ); + sqlite3_bind_int64 ( stmt, 7, int64_c ( i->second.getCounter() )); + sqlite3_bind_double( stmt, 8, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.variance() ) ) ); + sqlite3_bind_double( stmt, 9, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.total() / totalTime ) ) ); - sqlite3_finalize( stmt ); // free prepared statement + sqlite3_step ( stmt ); // execute statement + sqlite3_reset ( stmt ); // undo binding } + sqlite3_exec( dbHandle_, "END TRANSACTION;",0,0,0 ); + + sqlite3_finalize( stmt ); // free prepared statement +} - //******************************************************************************************************************* - /*! Stores a TimingTree in a Sqlite3 Database, and links it to a run +//******************************************************************************************************************* +/*! Stores a TimingTree in a Sqlite3 Database, and links it to a run * * The generated table is called "timingTree" * @@ -360,16 +360,16 @@ namespace postprocessing { * \param tt the TimingTree to store * \param name name of the timing tree ( as written to database column ) */ - //******************************************************************************************************************* - void SQLiteDB::storeTimingTree ( uint_t runId, - const WcTimingTree & tt, - const std::string & timingTreeName ) - { - sqlite3_exec( dbHandle_, "BEGIN;",0,0,0 ); +//******************************************************************************************************************* +void SQLiteDB::storeTimingTree ( uint_t runId, + const WcTimingTree & tt, + const std::string & timingTreeName ) +{ + sqlite3_exec( dbHandle_, "BEGIN;",0,0,0 ); - assert ( timingTreeName.length() > 0 && timingTreeName.length() < 255 ); + assert ( timingTreeName.length() > 0 && timingTreeName.length() < 255 ); - static const char * CREATE_TIMINGTREE_TABLE = + static const char * CREATE_TIMINGTREE_TABLE = "CREATE TABLE IF NOT EXISTS timingTree (" " id INTEGER PRIMARY KEY, " " runId INTEGER, " @@ -385,110 +385,134 @@ namespace postprocessing { " FOREIGN KEY (runId) REFERENCES runs(runId) " " );" ; - sqlite3_exec( dbHandle_, CREATE_TIMINGTREE_TABLE, 0,0,0 ); + sqlite3_exec( dbHandle_, CREATE_TIMINGTREE_TABLE, 0,0,0 ); - double totalTime = 0.0; - for (auto it = tt.getRawData().tree_.begin(); it != tt.getRawData().tree_.end(); ++it) - { - totalTime += it->second.timer_.total(); - } + double totalTime = 0.0; + for (auto it = tt.getRawData().tree_.begin(); it != tt.getRawData().tree_.end(); ++it) + { + totalTime += it->second.timer_.total(); + } - storeTimingNode(runId, std::numeric_limits<int>::max(), tt.getRawData(), timingTreeName, "Total", totalTime); + storeTimingNode(runId, std::numeric_limits<int>::max(), tt.getRawData(), timingTreeName, "Total", totalTime); - sqlite3_exec( dbHandle_, "END TRANSACTION;",0,0,0 ); - } + sqlite3_exec( dbHandle_, "END TRANSACTION;",0,0,0 ); +} - //******************************************************************************************************************* - /*! Stores a TimingNode recursively in a Sqlite3 Database, and links it together +//******************************************************************************************************************* +/*! Stores a TimingNode recursively in a Sqlite3 Database, and links it together * * \param runId primary key of the run, as returned by storeRun() * \param parentId parent key of the node * \param tn the TimingNode to store * \param name name of the timing tree ( as written to database column ) */ - //******************************************************************************************************************* - void SQLiteDB::storeTimingNode ( const uint_t runId, - const int parentId, - const WcTimingNode & tn, - const std::string & timingTreeName, - const std::string & sweep, - const double totalTime ) - { - static const char * INSERT_STATEMENT = - " INSERT INTO timingTree (runId,name,parentId,sweep,average,min,max,count,variance,percentage) " - " VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )"; - - sqlite3_stmt *stmt = NULL; - auto retVal = sqlite3_prepare_v2(dbHandle_, INSERT_STATEMENT, -1, &stmt, 0 ); - if ( retVal != SQLITE_OK ) { - WALBERLA_LOG_WARNING( "Failed to prepare SQL Insert statement (" << retVal << ")." ); - return; - } - - sqlite3_bind_int64 ( stmt, 1, int64_c(runId) ); - sqlite3_bind_text ( stmt, 2, timingTreeName.c_str() , -1, SQLITE_STATIC ); - sqlite3_bind_int64 ( stmt, 3, parentId ); - sqlite3_bind_text ( stmt, 4, sweep.c_str() , -1, SQLITE_STATIC ); - sqlite3_bind_double( stmt, 5, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.average() ) ) ); - sqlite3_bind_double( stmt, 6, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.min() ) ) ); - sqlite3_bind_double( stmt, 7, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.max() ) ) ); - sqlite3_bind_int64 ( stmt, 8, int64_c ( tn.timer_.getCounter() )); - sqlite3_bind_double( stmt, 9, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.variance() ) ) ); - sqlite3_bind_double( stmt,10, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.total() / totalTime ) ) ); - - sqlite3_step ( stmt ); // execute statement - sqlite3_reset ( stmt ); // undo binding - sqlite3_finalize( stmt ); // free prepared statement - - int currentId = int_c( sqlite3_last_insert_rowid( dbHandle_ ) ); - - for ( auto i = tn.tree_.begin(); i != tn.tree_.end(); ++i ) - { - storeTimingNode( runId, currentId, i->second, timingTreeName, i->first, totalTime); - } +//******************************************************************************************************************* +void SQLiteDB::storeTimingNode ( const uint_t runId, + const int parentId, + const WcTimingNode & tn, + const std::string & timingTreeName, + const std::string & sweep, + const double totalTime ) +{ + static const char * INSERT_STATEMENT = + " INSERT INTO timingTree (runId,name,parentId,sweep,average,min,max,count,variance,percentage) " + " VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )"; + + sqlite3_stmt *stmt = NULL; + auto retVal = sqlite3_prepare_v2(dbHandle_, INSERT_STATEMENT, -1, &stmt, 0 ); + if ( retVal != SQLITE_OK ) { + WALBERLA_LOG_WARNING( "Failed to prepare SQL Insert statement (" << retVal << ")." ); + return; } + sqlite3_bind_int64 ( stmt, 1, int64_c(runId) ); + sqlite3_bind_text ( stmt, 2, timingTreeName.c_str() , -1, SQLITE_STATIC ); + sqlite3_bind_int64 ( stmt, 3, parentId ); + sqlite3_bind_text ( stmt, 4, sweep.c_str() , -1, SQLITE_STATIC ); + sqlite3_bind_double( stmt, 5, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.average() ) ) ); + sqlite3_bind_double( stmt, 6, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.min() ) ) ); + sqlite3_bind_double( stmt, 7, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.max() ) ) ); + sqlite3_bind_int64 ( stmt, 8, int64_c ( tn.timer_.getCounter() )); + sqlite3_bind_double( stmt, 9, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.variance() ) ) ); + sqlite3_bind_double( stmt,10, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.total() / totalTime ) ) ); + sqlite3_step ( stmt ); // execute statement + sqlite3_reset ( stmt ); // undo binding + sqlite3_finalize( stmt ); // free prepared statement + int currentId = int_c( sqlite3_last_insert_rowid( dbHandle_ ) ); - - uint_t storeRunInSqliteDB( const string & dbFile, - const map<string, int> & integerProperties, - const map<string, string > & stringProperties, - const map<string, double > & realProperties, - const int busyTimeout ) - { - SQLiteDB db ( dbFile, busyTimeout ); - return db.storeRun( integerProperties, stringProperties, realProperties ); - } - uint_t storeRunInSqliteDB( const string & dbFile, - const map<string, int64_t> & integerProperties, - const map<string, string > & stringProperties, - const map<string, double > & realProperties, - const int busyTimeout ) - { - SQLiteDB db ( dbFile, busyTimeout ); - return db.storeRun( integerProperties, stringProperties, realProperties ); - } - - - void storeTimingPoolInSqliteDB ( const string & dbFile, uint_t runId, - const WcTimingPool & tp, - const std::string & timingPoolName, - const int busyTimeout ) - { - SQLiteDB db ( dbFile, busyTimeout ); - db.storeTimingPool( runId, tp, timingPoolName ); - } - - void storeTimingTreeInSqliteDB ( const string & dbFile, uint_t runId, - const WcTimingTree & tt, - const std::string & timingTreeName, - const int busyTimeout ) + for ( auto i = tn.tree_.begin(); i != tn.tree_.end(); ++i ) { - SQLiteDB db ( dbFile, busyTimeout ); - db.storeTimingTree( runId, tt, timingTreeName ); + storeTimingNode( runId, currentId, i->second, timingTreeName, i->first, totalTime); } +} + + + + + +uint_t storeRunInSqliteDB( const string & dbFile, + const map<string, int> & integerProperties, + const map<string, string > & stringProperties, + const map<string, double > & realProperties, + const int busyTimeout ) +{ + SQLiteDB db ( dbFile, busyTimeout ); + return db.storeRun( integerProperties, stringProperties, realProperties ); +} +uint_t storeRunInSqliteDB( const string & dbFile, + const map<string, int64_t> & integerProperties, + const map<string, string > & stringProperties, + const map<string, double > & realProperties, + const int busyTimeout ) +{ + SQLiteDB db ( dbFile, busyTimeout ); + return db.storeRun( integerProperties, stringProperties, realProperties ); +} + + +void storeAdditionalRunInfoInSqliteDB( const uint_t runId, + const string & dbFile, + const string & tableName, + const map<string, int> & integerProperties, + const map<string, string > & stringProperties, + const map<string, double > & realProperties, + const int busyTimeout ) +{ + SQLiteDB db ( dbFile, busyTimeout ); + return db.storeAdditionalRunInfo( runId, tableName, integerProperties, stringProperties, realProperties ); +} +void storeAdditionalRunInfoInSqliteDB( const uint_t runId, + const string & dbFile, + const string & tableName, + const map<string, int64_t> & integerProperties, + const map<string, string > & stringProperties, + const map<string, double > & realProperties, + const int busyTimeout ) +{ + SQLiteDB db ( dbFile, busyTimeout ); + return db.storeAdditionalRunInfo( runId, tableName, integerProperties, stringProperties, realProperties ); +} + + +void storeTimingPoolInSqliteDB ( const string & dbFile, uint_t runId, + const WcTimingPool & tp, + const std::string & timingPoolName, + const int busyTimeout ) +{ + SQLiteDB db ( dbFile, busyTimeout ); + db.storeTimingPool( runId, tp, timingPoolName ); +} + +void storeTimingTreeInSqliteDB ( const string & dbFile, uint_t runId, + const WcTimingTree & tt, + const std::string & timingTreeName, + const int busyTimeout ) +{ + SQLiteDB db ( dbFile, busyTimeout ); + db.storeTimingTree( runId, tt, timingTreeName ); +} } // namespace postprocessing } // namespace walberla diff --git a/src/postprocessing/sqlite/SQLite.h b/src/postprocessing/sqlite/SQLite.h index c4bf4650eaaf4e074c48a9b31e27645f1e535186..19e0855fa474cb4f055b634f4768a320b54e3cff 100644 --- a/src/postprocessing/sqlite/SQLite.h +++ b/src/postprocessing/sqlite/SQLite.h @@ -37,74 +37,86 @@ struct sqlite3; namespace walberla { namespace postprocessing { - using std::string; - using std::map; - - - // Time in seconds the process waits if database is locked - const int BUSY_TIMEOUT = 30; - - - - class SQLiteDB - { - private: - - public: - SQLiteDB ( const string & dbFile, const int busyTimeout = BUSY_TIMEOUT ); - ~SQLiteDB(); - - uint_t storeRun ( const map<string, int> & integerProperties, - const map<string, string > & stringProperties , - const map<string, double > & realProperties); - - uint_t storeRun ( const map<string, int64_t> & integerProperties, - const map<string, string > & stringProperties , - const map<string, double > & realProperties); - - void storeAdditionalRunInfo( uint_t runId, const std::string & tableName, - const map<string, int> & integerProperties, - const map<string, string > & stringProperties , - const map<string, double > & realProperties ); - - void storeAdditionalRunInfo( uint_t runId, const std::string & tableName, - const map<string, int64_t> & integerProperties, - const map<string, string > & stringProperties , - const map<string, double > & realProperties ); - - void storeTimingPool ( uint_t runId, const WcTimingPool & tp, const std::string & name ); - void storeTimingTree ( uint_t runId, const WcTimingTree & tt, const std::string & timingTreeName ); - - private: - void storeTimingNode ( const uint_t runId, - const int parentId, - const WcTimingNode & tn, - const std::string & timingTreeName, - const std::string & sweep, - const double totalTime ); - - bool valid_; - sqlite3 * dbHandle_; - std::string file_; - }; - - uint_t storeRunInSqliteDB( const string & dbFile, - const map<string, int> & integerProperties= map<string,int>(), - const map<string, string > & stringProperties = map<string,string>(), - const map<string, double > & realProperties = map<string,double>(), - const int busyTimeout = BUSY_TIMEOUT ); - - uint_t storeRunInSqliteDB( const string & dbFile, - const map<string, int64_t> & integerProperties= map<string,int64_t>(), - const map<string, string > & stringProperties = map<string,string>(), - const map<string, double > & realProperties = map<string,double>(), - const int busyTimeout = BUSY_TIMEOUT ); - - void storeTimingPoolInSqliteDB( const string & dbFile, uint_t runId, const WcTimingPool & tp, - const std::string & name, const int busyTimeout = BUSY_TIMEOUT ); - - void storeTimingTreeInSqliteDB( const string & dbFile, uint_t runId, const WcTimingTree & tt, - const std::string & name, const int busyTimeout = BUSY_TIMEOUT ); +using std::string; +using std::map; + + +// Time in seconds the process waits if database is locked +const int BUSY_TIMEOUT = 30; + + + +class SQLiteDB +{ +private: + +public: + SQLiteDB ( const string & dbFile, const int busyTimeout = BUSY_TIMEOUT ); + ~SQLiteDB(); + + uint_t storeRun ( const map<string, int> & integerProperties, + const map<string, string > & stringProperties , + const map<string, double > & realProperties); + + uint_t storeRun ( const map<string, int64_t> & integerProperties, + const map<string, string > & stringProperties , + const map<string, double > & realProperties); + + void storeAdditionalRunInfo( uint_t runId, const std::string & tableName, + const map<string, int> & integerProperties, + const map<string, string > & stringProperties , + const map<string, double > & realProperties ); + + void storeAdditionalRunInfo( uint_t runId, const std::string & tableName, + const map<string, int64_t> & integerProperties, + const map<string, string > & stringProperties , + const map<string, double > & realProperties ); + + void storeTimingPool ( uint_t runId, const WcTimingPool & tp, const std::string & name ); + void storeTimingTree ( uint_t runId, const WcTimingTree & tt, const std::string & timingTreeName ); + +private: + void storeTimingNode ( const uint_t runId, + const int parentId, + const WcTimingNode & tn, + const std::string & timingTreeName, + const std::string & sweep, + const double totalTime ); + + bool valid_; + sqlite3 * dbHandle_; + std::string file_; +}; + +uint_t storeRunInSqliteDB( const string & dbFile, + const map<string, int> & integerProperties= map<string,int>(), + const map<string, string > & stringProperties = map<string,string>(), + const map<string, double > & realProperties = map<string,double>(), + const int busyTimeout = BUSY_TIMEOUT ); + +uint_t storeRunInSqliteDB( const string & dbFile, + const map<string, int64_t> & integerProperties= map<string,int64_t>(), + const map<string, string > & stringProperties = map<string,string>(), + const map<string, double > & realProperties = map<string,double>(), + const int busyTimeout = BUSY_TIMEOUT ); + +void storeAdditionalRunInfoInSqliteDB( const string & dbFile, + const map<string, int> & integerProperties= map<string,int>(), + const map<string, string > & stringProperties = map<string,string>(), + const map<string, double > & realProperties = map<string,double>(), + const int busyTimeout = BUSY_TIMEOUT ); + +void storeAdditionalRunInfoInSqliteDB( const string & dbFile, + const map<string, int64_t> & integerProperties= map<string,int64_t>(), + const map<string, string > & stringProperties = map<string,string>(), + const map<string, double > & realProperties = map<string,double>(), + const int busyTimeout = BUSY_TIMEOUT ); + +void storeTimingPoolInSqliteDB( const string & dbFile, uint_t runId, const WcTimingPool & tp, + const std::string & name, const int busyTimeout = BUSY_TIMEOUT ); + +void storeTimingTreeInSqliteDB( const string & dbFile, uint_t runId, const WcTimingTree & tt, + const std::string & name, const int busyTimeout = BUSY_TIMEOUT ); diff --git a/src/python_coupling/DictWrapper.h b/src/python_coupling/DictWrapper.h index 912ce3a830aa9930ca1130b096a34ec0b4a9d2dc..0d2f0cab139433909ec078d7f1cf2b44e15e0a72 100644 --- a/src/python_coupling/DictWrapper.h +++ b/src/python_coupling/DictWrapper.h @@ -28,7 +28,9 @@ #include "PythonWrapper.h" #include "core/DataTypes.h" #include "core/Abort.h" -#include <boost/bind.hpp> + +#include <functional> + namespace walberla { namespace python_coupling { diff --git a/src/python_coupling/DictWrapper.impl.h b/src/python_coupling/DictWrapper.impl.h index 400eb2e7f09e4855cd2d1ffdb630b2dfb6ac6448..b6ffecb9be49db88624e5461c1f9b20ab5670d1b 100644 --- a/src/python_coupling/DictWrapper.impl.h +++ b/src/python_coupling/DictWrapper.impl.h @@ -19,6 +19,8 @@ // //====================================================================================================================== +#include <functional> + namespace walberla { namespace python_coupling { @@ -113,7 +115,7 @@ inline void runPythonObject( boost::python::object obj ) { template<> inline std::function<void()> DictWrapper::get( const std::string & name ) { boost::python::object obj ( d_[name] ); - return boost::bind( &runPythonObject, obj ); + return std::bind( &runPythonObject, obj ); } template<> diff --git a/src/python_coupling/Manager.h b/src/python_coupling/Manager.h index b6294b6fb0a6f218585b1e75bcc9d1bf5ba262ed..ed843ff11649c00ecfedf7b3e02713d8ce4afdb5 100644 --- a/src/python_coupling/Manager.h +++ b/src/python_coupling/Manager.h @@ -61,7 +61,7 @@ namespace python_coupling { boost::python::object testBlockData( IBlock & block, BlockDataID blockDataID ) { BlockDataToObjectTester tester( &block, blockDataID ); - for_each_noncopyable_type< TypeList > ( boost::ref(tester) ); + for_each_noncopyable_type< TypeList > ( std::ref(tester) ); return tester.getResult(); } diff --git a/src/python_coupling/basic_exports/BasicExports.cpp b/src/python_coupling/basic_exports/BasicExports.cpp index a3e4a8f31cbeb1715515319c2b6ff0e37bbe1e42..724efcfce421d3d171604a59617c3e4d6dfa15bc 100644 --- a/src/python_coupling/basic_exports/BasicExports.cpp +++ b/src/python_coupling/basic_exports/BasicExports.cpp @@ -43,6 +43,8 @@ #include <boost/version.hpp> +#include <functional> + using namespace boost::python; @@ -842,7 +844,7 @@ object * blockDataCreationHelper( IBlock * block, StructuredBlockStorage * bs, uint_t StructuredBlockStorage_addBlockData( StructuredBlockStorage & s, const std::string & name, object functionPtr ) { BlockDataID res = s.addStructuredBlockData(name) - << StructuredBlockDataCreator<object>( boost::bind( &blockDataCreationHelper, _1,_2, functionPtr ) ); + << StructuredBlockDataCreator<object>( std::bind( &blockDataCreationHelper, std::placeholders::_1, std::placeholders::_2, functionPtr ) ); //TODO extend this for moving block data ( packing und unpacking with pickle ) return res; } diff --git a/src/python_coupling/helper/MplHelpers.h b/src/python_coupling/helper/MplHelpers.h index 640f45637b09d10dc54904250749830dea43fbc8..d9b0086647f491efacf3d7bf56c060124819b66c 100644 --- a/src/python_coupling/helper/MplHelpers.h +++ b/src/python_coupling/helper/MplHelpers.h @@ -28,8 +28,8 @@ #include <boost/mpl/pair.hpp> #include <boost/mpl/transform.hpp> -#include <boost/bind.hpp> +#include <functional> #include <map> @@ -102,7 +102,7 @@ public: return map_[ blockDataID ]; Exporter exporter( block_, blockDataID ); - for_each_noncopyable_type< FieldTypeList> ( boost::ref(exporter) ); + for_each_noncopyable_type< FieldTypeList> ( std::ref(exporter) ); map_[ blockDataID ] = exporter.result; return exporter.result; } diff --git a/src/timeloop/PerformanceMeter.cpp b/src/timeloop/PerformanceMeter.cpp index 7af5f847d18ba2ae2bc51049fbe8706a3d30a0a7..8842912156ab1971cd1ca5a41984d550174f9934 100644 --- a/src/timeloop/PerformanceMeter.cpp +++ b/src/timeloop/PerformanceMeter.cpp @@ -53,7 +53,7 @@ namespace timeloop { *******************************************************************************************************************/ std::function<void () > PerformanceMeter::getBeforeFunction() { - return boost::bind ( &PerformanceMeter::timingStart, this ); + return std::bind ( &PerformanceMeter::timingStart, this ); } @@ -66,7 +66,7 @@ namespace timeloop { *******************************************************************************************************************/ std::function<void () > PerformanceMeter::getAfterFunction() { - return boost::bind ( &PerformanceMeter::timingEnd, this ); + return std::bind ( &PerformanceMeter::timingEnd, this ); } diff --git a/src/timeloop/PerformanceMeter.h b/src/timeloop/PerformanceMeter.h index 732121789149a1553e927fe2eb5d24e8ffa07846..731f968fe7046e95e03f7ac2e7953119fce48f57 100644 --- a/src/timeloop/PerformanceMeter.h +++ b/src/timeloop/PerformanceMeter.h @@ -23,9 +23,7 @@ #include "core/timing/Timer.h" #include "domain_decomposition/StructuredBlockStorage.h" -#include <boost/bind.hpp> #include <functional> - #include <iostream> #include <map> #include <string> @@ -180,7 +178,7 @@ namespace timeloop { typename FField::flag_t activeMask, uint_t countFreq , real_t scaling ) { - this->addMeasurement( name, boost::bind( flagFieldCountFunction<FField>, _1, flagFieldID, activeMask ), + this->addMeasurement( name, std::bind( flagFieldCountFunction<FField>, std::placeholders::_1, flagFieldID, activeMask ), countFreq, scaling ); } diff --git a/src/timeloop/SelectableFunctionCreators.h b/src/timeloop/SelectableFunctionCreators.h index b6762e469e37afc1f3c093c76af35c822731ec82..4deaa2ce49eea46714205b7198935b105a9d7b1b 100644 --- a/src/timeloop/SelectableFunctionCreators.h +++ b/src/timeloop/SelectableFunctionCreators.h @@ -25,7 +25,6 @@ #include "core/uid/SUID.h" #include "domain_decomposition/BlockStorage.h" -#include <boost/bind.hpp> #include <functional> #include <string> @@ -177,7 +176,7 @@ namespace timeloop { BlockDataID bdId = bs_.addBlockData() << bdCreator; // add a sweep function that fetches the block data sweep and executes it - auto sweepFunc = boost::bind ( executeSweepOnBlock<SweepClass>, _1, bdId ); + auto sweepFunc = std::bind ( executeSweepOnBlock<SweepClass>, std::placeholders::_1, bdId ); ( *this ) << Sweep ( sweepFunc, sw.identifier_, sw.requiredSelectors_, sw.incompatibleSelectors_ ); return *this; diff --git a/src/vtk/Initialization.cpp b/src/vtk/Initialization.cpp index d551086d5192ed5c2a824c7eef9cbe3a5a2adfa2..bac98bdb96f8871e12f92510aa86f968c1993c3b 100644 --- a/src/vtk/Initialization.cpp +++ b/src/vtk/Initialization.cpp @@ -29,7 +29,8 @@ #include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/split.hpp> -#include <boost/bind.hpp> + +#include <functional> namespace walberla { @@ -43,7 +44,7 @@ static void splitVector( T& x, T& y, T& z, const Config::BlockHandle& bb, const std::vector< std::string > coordinates; std::string vector = bb.getParameter< std::string >( vertex ); boost::split( coordinates, vector, boost::is_any_of("<,> \t") ); - coordinates.erase( std::remove_if( coordinates.begin(), coordinates.end(), boost::bind( &std::string::empty, _1 ) ), coordinates.end() ); + coordinates.erase( std::remove_if( coordinates.begin(), coordinates.end(), std::bind( &std::string::empty, std::placeholders::_1 ) ), coordinates.end() ); if( coordinates.size() != 3 ) WALBERLA_ABORT( errorMsg ); @@ -60,7 +61,7 @@ static std::vector< std::string > splitList( const std::string& string ) std::vector< std::string > list; boost::split( list, string, boost::is_any_of(", \t") ); - list.erase( std::remove_if( list.begin(), list.end(), boost::bind( &std::string::empty, _1 ) ), list.end() ); + list.erase( std::remove_if( list.begin(), list.end(), std::bind( &std::string::empty, std::placeholders::_1 ) ), list.end() ); return list; } @@ -71,7 +72,7 @@ static void addStates( Set<SUID>& set, const std::string& string ) { std::vector< std::string > states; boost::split( states, string, boost::is_any_of(", \t") ); - states.erase( std::remove_if( states.begin(), states.end(), boost::bind( &std::string::empty, _1 ) ), states.end() ); + states.erase( std::remove_if( states.begin(), states.end(), std::bind( &std::string::empty, std::placeholders::_1 ) ), states.end() ); for( auto it = states.begin(); it != states.end(); ++it ) set += SUID( *it ); diff --git a/tests/core/CMakeLists.txt b/tests/core/CMakeLists.txt index 6885cf97661fa507cc240a45207b63a62aec4a43..ddb9907147e78dbba1d6a9d5fd07be6f2dc033e6 100644 --- a/tests/core/CMakeLists.txt +++ b/tests/core/CMakeLists.txt @@ -143,13 +143,6 @@ waLBerla_execute_test( NAME SetReductionTest27 COMMAND $<TARGET_FILE:SetReductio waLBerla_compile_test( FILES mpi/ProbeVsExtraMessage.cpp DEPENDS postprocessing) -############## -# ptrvector # -############## - -waLBerla_compile_test( NAME PtrVector FILES ptrvector/PtrVector.cpp ) -waLBerla_execute_test( NAME PtrVector ) - ############## # selectable # ############## diff --git a/tests/core/mpi/BufferTest.cpp b/tests/core/mpi/BufferTest.cpp index c34a1ef8e89d2a138031ba1dde8092be69e7f40a..741edc1f85340215798bc848b7a275adeb9e30c6 100644 --- a/tests/core/mpi/BufferTest.cpp +++ b/tests/core/mpi/BufferTest.cpp @@ -122,6 +122,16 @@ void initBoostArray( boost::array< T, N > & array ) *it = dist( rng ); } +template<typename T, std::size_t N> +void initStdArray( std::array< T, N > & array ) +{ + static std::mt19937 rng; + std::uniform_int_distribution<T> dist; + + for( auto it = array.begin(); it != array.end(); ++it ) + *it = dist( rng ); +} + /// Simulates one send and receive operation /// data is put into send buffer and copied to RecvBuffer @@ -153,6 +163,7 @@ void bufferTest() std::multimap<unsigned int, walberla::int64_t> stdMultiMap, stdMultiMapEmpty; boost::array< unsigned int, 19 > boostArray; + std::array < unsigned int, 19 > stdArray; initVecBool(boolStdVec); initIntegerContainer(stdVec); @@ -163,6 +174,7 @@ void bufferTest() initIntegerMap(stdMap); initIntegerMap(stdMultiMap); initBoostArray(boostArray); + initStdArray(stdArray); // Create send buffer and put two values in it GenericSendBuffer<T> sb; @@ -178,7 +190,7 @@ void bufferTest() sb << stdMultiSet << stdMultiSetEmpty; sb << stdMap << stdMapEmpty; sb << stdMultiMap << stdMultiMapEmpty; - sb << boostArray; + sb << boostArray << stdArray; // Copying //RecvBuffer<T> rb; @@ -209,6 +221,7 @@ void bufferTest() std::multimap<unsigned int, walberla::int64_t> recvStdMultiMap, recvStdMultiMapEmpty; boost::array<unsigned int, 19> recvBoostArray; + std::array <unsigned int, 19> recvStdArray; rb >> recvD >> recvI; rb >> recvVec >> recvMat; @@ -222,7 +235,7 @@ void bufferTest() rb >> recvStdMultiSet >> recvStdMultiSetEmpty; rb >> recvStdMap >> recvStdMapEmpty; rb >> recvStdMultiMap >> recvStdMultiMapEmpty; - rb >> recvBoostArray; + rb >> recvBoostArray >> recvStdArray; // Validate WALBERLA_CHECK_FLOAT_EQUAL(recvD,testDouble); @@ -254,6 +267,7 @@ void bufferTest() WALBERLA_CHECK_EQUAL(recvStdMultiMapEmpty, stdMultiMapEmpty); WALBERLA_CHECK_EQUAL(recvBoostArray, boostArray); + WALBERLA_CHECK_EQUAL(recvStdArray, stdArray); } diff --git a/tests/core/ptrvector/PtrVector.cpp b/tests/core/ptrvector/PtrVector.cpp deleted file mode 100644 index 8ae38bdeaff93a71ac5187d7c223f87670de0b7f..0000000000000000000000000000000000000000 --- a/tests/core/ptrvector/PtrVector.cpp +++ /dev/null @@ -1,98 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file PtrVector.cpp -//! \ingroup field -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -// -//====================================================================================================================== - -#include "core/ptrvector/PtrVector.h" -#include "core/ptrvector/policies/NoDelete.h" - -#include "core/debug/TestSubsystem.h" - -using namespace walberla; - -struct A{ - int c; - int val; - static int refCount; - - explicit A(int v = 0) : c(0), val(v) { ++refCount; } - virtual ~A(){ --refCount; } -}; - -struct B : public A { - B() : A(1) {} -}; - -struct C : public A { - C() : A(2) {} -}; - -int A::refCount = 0; - -int main( int /*argc*/, char** /*argv*/ ) -{ - debug::enterTestMode(); - { - auto a = new A(); - auto b = new B(); - auto c = new C(); - - WALBERLA_CHECK_EQUAL(A::refCount, 3); - - PtrVector<A, PtrDelete> vec; - vec.pushBack(a); - vec.pushBack(b); - vec.pushBack(c); - - WALBERLA_CHECK_EQUAL(A::refCount, 3); - - for (auto it = vec.begin(); it!=vec.end(); ++it){ - ++(it->c); - } - for (auto it = vec.begin<B>(); it!=vec.end<B>(); ++it){ - ++(it->c); - } - - WALBERLA_CHECK_EQUAL(a->c, 1); - WALBERLA_CHECK_EQUAL(b->c, 2); - - vec.erase(++vec.begin()); - int sum = 0; - for (auto it = vec.begin(); it!=vec.end(); ++it){ - sum += it->val; - } - - WALBERLA_CHECK_EQUAL(sum, 2); - } - WALBERLA_CHECK_EQUAL(A::refCount, 0); - - auto a = new A(); - auto b = new B(); - WALBERLA_CHECK_EQUAL(A::refCount, 2); - { - PtrVector<A, NoDelete> vec; - vec.pushBack(a); - vec.pushBack(b); - WALBERLA_CHECK_EQUAL(A::refCount, 2); - } - WALBERLA_CHECK_EQUAL(A::refCount, 2); - - delete a; - delete b; -} diff --git a/tests/domain_decomposition/CMakeLists.txt b/tests/domain_decomposition/CMakeLists.txt index 9ab9ff72cb0418ca4ce77b09fe7e945c29ecb42e..2c7cae2624be9baca0d50259c941223c233aa4f9 100644 --- a/tests/domain_decomposition/CMakeLists.txt +++ b/tests/domain_decomposition/CMakeLists.txt @@ -6,3 +6,6 @@ waLBerla_compile_test( NAME PeriodicIntersect FILES PeriodicIntersect.cpp DEPENDS core blockforest ) waLBerla_execute_test( NAME PeriodicIntersect ) + +waLBerla_compile_test( NAME PeriodicIntersectionVolume FILES PeriodicIntersectionVolume.cpp DEPENDS core blockforest ) +waLBerla_execute_test( NAME PeriodicIntersectionVolume ) diff --git a/tests/domain_decomposition/PeriodicIntersectionVolume.cpp b/tests/domain_decomposition/PeriodicIntersectionVolume.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cb48e5777aef6ecd6054ad984c1a62b0a6a7ad45 --- /dev/null +++ b/tests/domain_decomposition/PeriodicIntersectionVolume.cpp @@ -0,0 +1,99 @@ +//====================================================================================================================== +// +// This file is part of waLBerla. waLBerla is free software: you can +// redistribute it and/or modify it under the terms of the GNU General Public +// License as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// waLBerla is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. +// +//! \file DataTypesTest.cpp +//! \author Sebastian Eibl <sebastian.eibl@fau.de> +// +//====================================================================================================================== + +#include "core/Environment.h" +#include "core/math/AABB.h" +#include "core/debug/Debug.h" +#include "core/debug/TestSubsystem.h" +#include "core/logging/Logging.h" + +#include "domain_decomposition/PeriodicIntersectionVolume.h" + +#include "stencil/D3Q27.h" + +int main( int argc, char** argv ) +{ + using namespace walberla; + using namespace walberla::domain_decomposition; + + debug::enterTestMode(); + + Environment walberlaEnv( argc, argv ); + WALBERLA_UNUSED(walberlaEnv); + + std::array< bool, 3 > periodic{{true, true, true}}; + math::AABB domain(real_t(0),real_t(0),real_t(0),real_t(100),real_t(100),real_t(100)); + math::AABB box1(real_t(0),real_t(0),real_t(0),real_t(10),real_t(10),real_t(10)); + math::AABB box2(real_t(0),real_t(0),real_t(0),real_t(10),real_t(10),real_t(10)); + + for (int multiple = 0; multiple < 3; ++multiple) + { + for (auto dir = stencil::D3Q27::beginNoCenter(); dir != stencil::D3Q27::end(); ++dir) + { + Vector3<real_t> shift( + real_c(dir.cx()) * (real_t(9) + domain.xSize() * real_c(multiple)), + real_c(dir.cy()) * (real_t(9) + domain.ySize() * real_c(multiple)), + real_c(dir.cz()) * (real_t(9) + domain.zSize() * real_c(multiple))); + box2.setCenter(shift + box1.center()); + real_t vol = periodicIntersectionVolume(periodic, domain, box1, box2); + + switch (dir.direction()) + { + case stencil::BNE: + case stencil::BNW: + case stencil::BSE: + case stencil::BSW: + case stencil::TNE: + case stencil::TNW: + case stencil::TSE: + case stencil::TSW: + WALBERLA_CHECK_FLOAT_EQUAL(vol, real_t(1)); + break; + case stencil::BN: + case stencil::BW: + case stencil::BS: + case stencil::BE: + case stencil::TN: + case stencil::TW: + case stencil::TS: + case stencil::TE: + case stencil::NE: + case stencil::NW: + case stencil::SE: + case stencil::SW: + WALBERLA_CHECK_FLOAT_EQUAL(vol, real_t(10)); + break; + case stencil::B: + case stencil::T: + case stencil::N: + case stencil::W: + case stencil::S: + case stencil::E: + WALBERLA_CHECK_FLOAT_EQUAL(vol, real_t(100)); + break; + default: + WALBERLA_CHECK(false, "Should not end up here!"); + break; + } + } + } + + return EXIT_SUCCESS; +} diff --git a/tests/fft/FftTest.cpp b/tests/fft/FftTest.cpp index 58d80c486de68e7c33d9e2a14263fd08cdd0eeb7..99e934dbfca25d21ad8fb7883634ac6d591c6bd4 100644 --- a/tests/fft/FftTest.cpp +++ b/tests/fft/FftTest.cpp @@ -41,7 +41,7 @@ int main (int argc, char** argv) { Field_T *data_in = block->getData< Field_T >( originalFieldId ); Field_T *data_out = block->getData< Field_T >( fftFieldId ); - WALBERLA_FOR_ALL_CELLS_XYZ(data_in, { + WALBERLA_FOR_ALL_CELLS_XYZ_OMP(data_in, omp critical, { Vector3<real_t> point( real_c(x), real_c(y), real_c(z) ); blocks->transformBlockLocalToGlobal(point, *block); data_in->get(x,y,z) = real_c(std::ranlux48_base(uint_c(point[0])+(uint_c(point[1])*L+uint_c(point[2]))*L)())*real_c(std::pow(2,-48)); diff --git a/tests/geometry/VoxelFileTest.cpp b/tests/geometry/VoxelFileTest.cpp index 3d6d18fa1654edfacffe3637801e0f4274576557..e93b1cfa157ae4c023c8fe1bcbf330d2e3ac8775 100644 --- a/tests/geometry/VoxelFileTest.cpp +++ b/tests/geometry/VoxelFileTest.cpp @@ -53,7 +53,7 @@ #include "core/mpi/MPIManager.h" #include "core/Filesystem.h" -#include <boost/foreach.hpp> + #include <random> #ifdef _MSC_VER diff --git a/tests/lbm/DiffusionTest.cpp b/tests/lbm/DiffusionTest.cpp index a6f126a35deeea6364a809f6c18edcfe5d97f79a..4bed8c474f97b469ff3893fcfe3049fa4fe10a3c 100644 --- a/tests/lbm/DiffusionTest.cpp +++ b/tests/lbm/DiffusionTest.cpp @@ -79,6 +79,8 @@ #include <boost/lexical_cast.hpp> +#include <functional> + namespace walberla { @@ -280,16 +282,16 @@ int run( int argc, char **argv ) scheme.addPackInfo( make_shared< field::communication::PackInfo< AdvDiffPDFField > >( srcFieldID ) ); timeloop.addFuncBeforeTimeStep( scheme, "Communication" ); - using boost::ref; + using std::ref; - timeloop.add() << Sweep( boost::bind( hydroFunc, _1, velFieldID, u, tperiod, ref(timestep) ), "Hydro Func" ); + timeloop.add() << Sweep( std::bind( hydroFunc, std::placeholders::_1, velFieldID, u, tperiod, ref(timestep) ), "Hydro Func" ); timeloop.add() << Sweep( makeSharedSweep( lbm::makeCellwiseAdvectionDiffusionSweep< AdvDiffLatticeModel, VectorField, MyFlagField >( srcFieldID, velFieldID, flagFieldID, getFluidFlag() ) ), "LBM_SRT" ); - timeloop.add() << BeforeFunction( boost::bind( prepFunc, u[dim], dv, D, cperiod, tperiod, ref(timestep), ref(cosi), ref(sisi), ref(sexp) ), "prepare test" ) - << Sweep ( boost::bind( testFunc<AdvDiffPDFField>, _1, srcFieldID, dim, v, cperiod, ref(cosi), ref(sisi), ref(sexp), ref(E_mean_) ), "Test Func" ) - << AfterFunction ( boost::bind( incTimeFunc, ref(timestep) ), "increment time" ); + timeloop.add() << BeforeFunction( std::bind( prepFunc, u[dim], dv, D, cperiod, tperiod, ref(timestep), ref(cosi), ref(sisi), ref(sexp) ), "prepare test" ) + << Sweep ( std::bind( testFunc<AdvDiffPDFField>, std::placeholders::_1, srcFieldID, dim, v, cperiod, ref(cosi), ref(sisi), ref(sexp), ref(E_mean_) ), "Test Func" ) + << AfterFunction ( std::bind( incTimeFunc, ref(timestep) ), "increment time" ); // --- run timeloop --- // diff --git a/tests/lbm/boundary/SimpleDiffusionDirichlet.cpp b/tests/lbm/boundary/SimpleDiffusionDirichlet.cpp index d28603a3feb1553d8d321d7b2ab216bc3ef14960..1d4e95008f8987b97e9606d8230bfae2fa6b4990 100644 --- a/tests/lbm/boundary/SimpleDiffusionDirichlet.cpp +++ b/tests/lbm/boundary/SimpleDiffusionDirichlet.cpp @@ -76,6 +76,7 @@ #include <stdexcept> #include <array> +#include <functional> #include "gather/GnuPlotGraphWriter.h" #include "field/vtk/FlagFieldCellFilter.h" @@ -85,7 +86,6 @@ #include "vtk/VTKOutput.h" - namespace walberla { typedef GhostLayerField< real_t, 1 > ScalarField; @@ -138,7 +138,7 @@ shared_ptr< StructuredBlockForest > makeStructuredBlockStorage( uint_t length, u uint_t cells[] = { length, width, width }; uint_t blocks[] = { uint_t(1u), uint_t(1u), uint_t(1u) }; - sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, refinement ) ); + sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, refinement ) ); sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment ); sforest.init( @@ -249,6 +249,7 @@ public: #ifdef TEST_USES_VTK_OUTPUT error_.resize(time_); #endif + WALBERLA_UNUSED(maxValue_); } void operator()(); diff --git a/tests/lbm/codegen/SrtWithForceFieldModel.gen.py b/tests/lbm/codegen/SrtWithForceFieldModel.gen.py index 2ecb139fbbba9d4562a6781441f2d929f9404086..f004d38404605dc00412da91fccd66876f9e28d2 100644 --- a/tests/lbm/codegen/SrtWithForceFieldModel.gen.py +++ b/tests/lbm/codegen/SrtWithForceFieldModel.gen.py @@ -1,34 +1,34 @@ import sympy as sp from lbmpy.boundaries import NoSlip, UBB -from lbmpy_walberla import Field, generateLatticeModelFiles, RefinementScaling -from lbmpy.creationfunctions import createLatticeBoltzmannMethod -from lbmpy_walberla.boundary import createBoundaryClass +from lbmpy_walberla import Field, generate_lattice_model_files, RefinementScaling +from lbmpy.creationfunctions import create_lb_method +from lbmpy_walberla.boundary import create_boundary_class from pystencils_walberla.cmake_integration import codegen +import pystencils as ps # ------------- Lattice Model ------------------------------ -forceField = Field.createGeneric('force', spatialDimensions=3, indexDimensions=1, layout='fzyx') -force = [forceField(0), forceField(1), forceField(2)] +force_field = ps.fields("force(3): [3D]", layout='fzyx') omega = sp.Symbol("omega") scaling = RefinementScaling() -scaling.addStandardRelaxationRateScaling(omega) -scaling.addForceScaling(forceField) +scaling.add_standard_relaxation_rate_scaling(omega) +scaling.add_force_scaling(force_field) -generateLatticeModelFiles(className='SrtWithForceFieldModel', - method='srt', stencil='D3Q19', forceModel='guo', force=force, - relaxationRates=[omega], refinementScaling=scaling) +generate_lattice_model_files(class_name='SrtWithForceFieldModel', + method='srt', stencil='D3Q19', force_model='guo', force=force_field.center_vector, + relaxation_rates=[omega], refinement_scaling=scaling) def genBoundary(): boundary = UBB([0.05, 0, 0], dim=3, name="MyUBB") - method = createLatticeBoltzmannMethod(stencil='D3Q19', method='srt') - return createBoundaryClass(boundary, method) + method = create_lb_method(stencil='D3Q19', method='srt') + return create_boundary_class(boundary, method) def genNoSlip(): boundary = NoSlip(name='MyNoSlip') - method = createLatticeBoltzmannMethod(stencil='D3Q19', method='srt') - return createBoundaryClass(boundary, method) + method = create_lb_method(stencil='D3Q19', method='srt') + return create_boundary_class(boundary, method) codegen.register(['MyUBB.h', 'MyUBB.cpp'], genBoundary) codegen.register(['MyNoSlip.h', 'MyNoSlip.cpp',], genNoSlip) diff --git a/tests/lbm/refinement/CommunicationEquivalence.cpp b/tests/lbm/refinement/CommunicationEquivalence.cpp index 32f029d77f0f9cc621afa930578847da88f7e92f..6cd232235ec3695c4e0bae3ac14abc11b373b390 100644 --- a/tests/lbm/refinement/CommunicationEquivalence.cpp +++ b/tests/lbm/refinement/CommunicationEquivalence.cpp @@ -50,11 +50,10 @@ #include "timeloop/SweepTimeloop.h" -#include <boost/bind.hpp> - #include <algorithm> #include <cstdlib> #include <fstream> +#include <functional> //#define TEST_USES_VTK_OUTPUT #ifdef TEST_USES_VTK_OUTPUT @@ -190,7 +189,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( const uint_t le // initialize SetupBlockForest = determine domain decomposition SetupBlockForest sforest; - sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, levels ) ); + sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, levels ) ); sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment ); sforest.init( AABB( real_c(0), real_c(0), real_c(0), real_c( numberOfXBlocks * numberOfXCellsPerBlock ), diff --git a/tests/lbm/refinement/NonConstantDiffusion.cpp b/tests/lbm/refinement/NonConstantDiffusion.cpp index 12d96631abb827c9af7307103731a678c5b92999..dca9d0529341ce97b1e291f8ab0f92731e895722 100644 --- a/tests/lbm/refinement/NonConstantDiffusion.cpp +++ b/tests/lbm/refinement/NonConstantDiffusion.cpp @@ -75,6 +75,7 @@ #include <boost/lexical_cast.hpp> #include <stdexcept> +#include <functional> #include "gather/GnuPlotGraphWriter.h" #include "field/vtk/FlagFieldCellFilter.h" @@ -137,7 +138,7 @@ shared_ptr< StructuredBlockForest > makeStructuredBlockStorage( uint_t length, u uint_t cells[] = { length, width, width }; uint_t blocks[] = { uint_t(1u), uint_t(1u), uint_t(1u) }; - sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, refinement ) ); + sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, refinement ) ); sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment ); sforest.init( diff --git a/tests/lbm/refinement/Uniformity.cpp b/tests/lbm/refinement/Uniformity.cpp index 67e73915a3d4c01ee772e0688052e7365cb054bf..aabd8d6fb6fad931c7a3bcb91c038373a77c33ef 100644 --- a/tests/lbm/refinement/Uniformity.cpp +++ b/tests/lbm/refinement/Uniformity.cpp @@ -50,10 +50,9 @@ #include "timeloop/SweepTimeloop.h" -#include <boost/bind.hpp> - #include <algorithm> #include <cstdlib> +#include <functional> //#define TEST_USES_VTK_OUTPUT #ifdef TEST_USES_VTK_OUTPUT @@ -150,7 +149,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( const uint_t le // initialize SetupBlockForest = determine domain decomposition SetupBlockForest sforest; - sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, levels ) ); + sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, levels ) ); sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment ); sforest.init( AABB( real_c(0), real_c(0), real_c(0), real_c( numberOfXBlocks * numberOfXCellsPerBlock ), diff --git a/tests/mesh/MeshContainmentOctreeTest.cpp b/tests/mesh/MeshContainmentOctreeTest.cpp index 4e922e17a8e5f6a4a54f49437fccc32037052b91..40f542ddbfa20cc3afae192c5b70e9f875938af6 100644 --- a/tests/mesh/MeshContainmentOctreeTest.cpp +++ b/tests/mesh/MeshContainmentOctreeTest.cpp @@ -69,9 +69,9 @@ int main( int argc, char * argv[] ) auto aabb = computeAABB( *mesh ); - static const mesh::TriangleMesh::Point xAxis( 1, 0, 0 ); - static const mesh::TriangleMesh::Point yAxis( 0, 1, 0 ); - static const mesh::TriangleMesh::Point zAxis( 0, 0, 1 ); + //static const mesh::TriangleMesh::Point xAxis( 1, 0, 0 ); + //static const mesh::TriangleMesh::Point yAxis( 0, 1, 0 ); + //static const mesh::TriangleMesh::Point zAxis( 0, 0, 1 ); mesh::TriangleMesh::Point r = mesh::toOpenMesh( ( aabb.minCorner() - aabb.maxCorner() ).getNormalized() ); @@ -124,4 +124,4 @@ int main( int argc, char * argv[] ) int main( int argc, char * argv[] ) { return walberla::mesh::main( argc, argv ); -} \ No newline at end of file +} diff --git a/tests/mesh/MeshInitilizationTest.cpp b/tests/mesh/MeshInitilizationTest.cpp index cc98a3e5150eedb4a57374cee41d6ec88fae8827..494f212fb68abf7c99e626196168fa156f542092 100644 --- a/tests/mesh/MeshInitilizationTest.cpp +++ b/tests/mesh/MeshInitilizationTest.cpp @@ -102,7 +102,7 @@ void test( const std::string & meshFile, const uint_t numProcesses, const uint_t WALBERLA_LOG_INFO_ON_ROOT( "Creating SBF with StaticLevelwiseCurveBalanceWeighted Partitioner" ); bfc.setTargetProcessAssignmentFunction( blockforest::StaticLevelwiseCurveBalanceWeighted() ); auto sbf_default = bfc.createSetupBlockForest( Vector3<uint_t>(64,64,64), numProcesses ); - sbf_default->writeVTKOutput("sbf_default"); + //sbf_default->writeVTKOutput("sbf_default"); WALBERLA_LOG_INFO_ON_ROOT( sbf_default->toString() ); return; @@ -137,6 +137,37 @@ void test( const std::string & meshFile, const uint_t numProcesses, const uint_t #endif } +template< typename MeshType > +void testHelperFunctions( const std::string & meshFile, const uint_t numTotalBlocks ) +{ + auto mesh = make_shared<MeshType>(); + mesh::readAndBroadcast( meshFile, *mesh); + auto triDist = make_shared< mesh::TriangleDistance<MeshType> >( mesh ); + auto distanceOctree = make_shared< DistanceOctree< MeshType > >( triDist ); + + const real_t meshVolume = real_c( computeVolume( *mesh ) ); + const real_t blockVolume = meshVolume / real_c( numTotalBlocks ); + static const real_t cellsPersBlock = real_t(1000); + const real_t cellVolume = blockVolume / cellsPersBlock; + const real_t dx = std::pow( cellVolume, real_t(1) / real_t(3) ); + + WALBERLA_LOG_INFO_ON_ROOT( "Creating SBF with createStructuredBlockStorageInsideMesh with block size" ); + auto sbf0 = mesh::createStructuredBlockStorageInsideMesh( distanceOctree, dx, numTotalBlocks ); + + WALBERLA_LOG_INFO_ON_ROOT( "Creating SBF with createStructuredBlockStorageInsideMesh with block size" ); + Vector3<uint_t> blockSize( sbf0->getNumberOfXCells(), sbf0->getNumberOfYCells(), sbf0->getNumberOfZCells() ); + auto sbf1 = mesh::createStructuredBlockStorageInsideMesh( distanceOctree, dx, blockSize ); + + auto exteriorAabb = computeAABB( *mesh ).getScaled( real_t(2) ); + + WALBERLA_LOG_INFO_ON_ROOT( "Creating SBF with createStructuredBlockStorageInsideMesh with block size" ); + auto sbf2 = mesh::createStructuredBlockStorageOutsideMesh( exteriorAabb, distanceOctree, dx, numTotalBlocks ); + + WALBERLA_LOG_INFO_ON_ROOT( "Creating SBF with createStructuredBlockStorageInsideMesh with block size" ); + blockSize = Vector3<uint_t>( sbf2->getNumberOfXCells(), sbf2->getNumberOfYCells(), sbf2->getNumberOfZCells() ); + auto sbf3 = mesh::createStructuredBlockStorageOutsideMesh( exteriorAabb, distanceOctree, dx, blockSize ); +} + int main( int argc, char * argv[] ) { debug::enterTestMode(); @@ -155,6 +186,8 @@ int main( int argc, char * argv[] ) //test< mesh::FloatTriangleMesh >( meshFile, numProcesses, numTotalBlocks ); //test< mesh::PythonTriangleMesh >( meshFile, numProcesses, numTotalBlocks ); + testHelperFunctions< mesh::TriangleMesh >( meshFile, numTotalBlocks ); + return EXIT_SUCCESS; } diff --git a/tests/mesh/PeVTKMeshWriterTest.cpp b/tests/mesh/PeVTKMeshWriterTest.cpp index a765f30c4290e09240027168fd90591314c48eb4..5399af727b70e2a4a5015f3d6a74527127c8f5f4 100644 --- a/tests/mesh/PeVTKMeshWriterTest.cpp +++ b/tests/mesh/PeVTKMeshWriterTest.cpp @@ -42,6 +42,7 @@ #include <postprocessing/sqlite/SQLite.h> #include <vtk/VTKOutput.h> +#include <functional> #include <random> using namespace walberla; @@ -142,7 +143,7 @@ int main( int argc, char ** argv ) cr.setRelaxationParameter( real_t(0.7) ); cr.setGlobalLinearAcceleration( Vec3(0,0,5) ); - std::function<void(void)> syncCall = boost::bind( pe::syncNextNeighbors<BodyTuple>, boost::ref(*forest), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false ); + std::function<void(void)> syncCall = std::bind( pe::syncNextNeighbors<BodyTuple>, std::ref(*forest), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false ); typedef mesh::FloatPolyMesh OutputMeshType; typedef mesh::pe::DefaultTesselation<OutputMeshType> TesselationType; diff --git a/tests/pde/MGTest.cpp b/tests/pde/MGTest.cpp index e673a61090673c62fff051a88fa2d7fa9fa5a9dc..fa08a2bf8a08a5b6df3006fe842c032a90d38f43 100644 --- a/tests/pde/MGTest.cpp +++ b/tests/pde/MGTest.cpp @@ -160,6 +160,8 @@ int main( int argc, char** argv ) for( int i = 1; i < argc; ++i ) if( std::strcmp( argv[i], "--shortrun" ) == 0 ) shortrun = true; + const uint_t numLvl = shortrun ? uint_t(3) : uint_t(5); + const uint_t xBlocks = ( processes == uint_t(1) ) ? uint_t(1) : uint_t(2); const uint_t yBlocks = ( processes == uint_t(1) ) ? uint_t(1) : uint_t(2); const uint_t zBlocks = ( processes == uint_t(1) ) ? uint_t(1) : uint_t(2); @@ -201,19 +203,19 @@ int main( int argc, char** argv ) weights[ Stencil_T::idx[ stencil::T ] ] = real_t(-1) / ( blocks->dx() * blocks->dz() ); weights[ Stencil_T::idx[ stencil::B ] ] = real_t(-1) / ( blocks->dx() * blocks->dz() ); - auto solver = walberla::make_shared<pde::VCycles< Stencil_T > >( blocks, uId, fId, weights, - shortrun ? uint_t(1) : uint_t(20), // iterations - shortrun ? uint_t(3) : uint_t(5), // levels - 3, 3, 10, // pre-smoothing, post-smoothing, coarse-grid iterations - pde::ResidualNorm< Stencil_T >( blocks->getBlockStorage(), uId, fId, weights ), // residual norm functor - real_c(1e-12) ); // target precision - timeloop.addFuncBeforeTimeStep( makeSharedFunctor(solver), "Cell-centered multigrid V-cycles" ); + auto solverDCA = walberla::make_shared<pde::VCycles< Stencil_T > >( blocks, uId, fId, weights, + shortrun ? uint_t(1) : uint_t(20), // iterations + numLvl, // levels + 3, 3, 10, // pre-smoothing, post-smoothing, coarse-grid iterations + pde::ResidualNorm< Stencil_T >( blocks->getBlockStorage(), uId, fId, weights ), // residual norm functor + real_c(1e-12) ); // target precision + timeloop.addFuncBeforeTimeStep( makeSharedFunctor(solverDCA), "Cell-centered multigrid V-cycles with uniformly constant stencil" ); timeloop.run(); if( !shortrun ) { - auto & convrate = solver->convergenceRate(); + auto & convrate = solverDCA->convergenceRate(); for (uint_t i = 1; i < convrate.size(); ++i) { WALBERLA_LOG_RESULT_ON_ROOT("Convergence rate in iteration " << i << ": " << convrate[i]); @@ -224,7 +226,7 @@ int main( int argc, char** argv ) field::createVTKOutput< PdeField_T >( uId, *blocks, "solution" )(); } - // rerun the test with a stencil field + // rerun the test with a stencil field and DCA clearField<PdeField_T>( blocks, uId); initU( blocks, uId ); @@ -235,19 +237,52 @@ int main( int argc, char** argv ) copyWeightsToStencilField( blocks, weights, stencilId ); - solver = walberla::make_shared<pde::VCycles< Stencil_T > >( blocks, uId, fId, stencilId, - shortrun ? uint_t(1) : uint_t(20), // iterations - shortrun ? uint_t(3) : uint_t(5), // levels + pde::CoarsenStencilFieldsDCA<Stencil_T> coarsenWithDCA( blocks, numLvl, uint_t(2)); // Set up DCA object with operator order 2 (Laplace) + + solverDCA = walberla::make_shared<pde::VCycles< Stencil_T, decltype(coarsenWithDCA) > >( + blocks, uId, fId, stencilId, coarsenWithDCA, + shortrun ? uint_t(1) : uint_t(20), // iterations + numLvl, // levels + 3, 3, 10, // pre-smoothing, post-smoothing, coarse-grid iterations + pde::ResidualNormStencilField< Stencil_T >( blocks->getBlockStorage(), uId, fId, stencilId ), // residual norm functor + real_c(1e-12) ); // target precision + timeloop2.addFuncBeforeTimeStep( makeSharedFunctor(solverDCA), "Cell-centered multigrid V-cycles with stencil field and direct coarsening " ); + + timeloop2.run(); + + if( !shortrun ) + { + auto & convrate = solverDCA->convergenceRate(); + for (uint_t i = 1; i < convrate.size(); ++i) + { + WALBERLA_LOG_RESULT_ON_ROOT("Convergence rate in iteration " << i << ": " << convrate[i]); + WALBERLA_CHECK_LESS(convrate[i], real_t(0.1)); + } + } + + // rerun the test with a stencil field and GCA + + clearField<PdeField_T>( blocks, uId); + initU( blocks, uId ); + + SweepTimeloop timeloop3( blocks, uint_t(1) ); + + pde::CoarsenStencilFieldsGCA<Stencil_T> coarsenWithGCA( blocks, numLvl, real_t(2)); // Set up GCA object with overrelaxation factor 2 (only valid for Poisson equation) + + auto solverGCA = walberla::make_shared<pde::VCycles< Stencil_T, decltype(coarsenWithGCA) > >( + blocks, uId, fId, stencilId, coarsenWithGCA, + shortrun ? uint_t(1) : uint_t(20), // iterations + numLvl, // levels 3, 3, 10, // pre-smoothing, post-smoothing, coarse-grid iterations pde::ResidualNormStencilField< Stencil_T >( blocks->getBlockStorage(), uId, fId, stencilId ), // residual norm functor real_c(1e-12) ); // target precision - timeloop2.addFuncBeforeTimeStep( makeSharedFunctor(solver), "Cell-centered multigrid V-cycles" ); + timeloop3.addFuncBeforeTimeStep( makeSharedFunctor(solverGCA), "Cell-centered multigrid V-cycles with stencil field and Galerkin coarsening " ); - timeloop2.run(); + timeloop3.run(); if( !shortrun ) { - auto & convrate = solver->convergenceRate(); + auto & convrate = solverGCA->convergenceRate(); for (uint_t i = 1; i < convrate.size(); ++i) { WALBERLA_LOG_RESULT_ON_ROOT("Convergence rate in iteration " << i << ": " << convrate[i]); diff --git a/tests/pe/BodyFlags.cpp b/tests/pe/BodyFlags.cpp index 901e85c71bf41bb6b0c4238fc8fff6aa6e550db1..db7e82ce8f6b3c4890ffb3949bbe5fba7b3dcc4f 100644 --- a/tests/pe/BodyFlags.cpp +++ b/tests/pe/BodyFlags.cpp @@ -71,12 +71,12 @@ int main( int argc, char ** argv ) MaterialID iron = Material::find("iron"); - SphereID refGlobalSphere = new Sphere(1, 0, Vec3(9, 9, 9), Vec3(0,0,0), Quat(), 3, iron, true, false, true); - refGlobalSphere->setLinearVel(Vec3(2,2,2)); + Sphere refGlobalSphere(1, 0, Vec3(9, 9, 9), Vec3(0,0,0), Quat(), 3, iron, true, false, true); + refGlobalSphere.setLinearVel(Vec3(2,2,2)); SphereID globalSphere = createSphere( *globalStorage, forest->getBlockStorage(), storageID, 0, Vec3(9,9,9), 3, iron, true, false, true); globalSphere->setLinearVel(Vec3(2,2,2)); - SphereID refFixedSphere = new Sphere(2, 0, Vec3(9,9,14), Vec3(0,0,0), Quat(), 3, iron, false, false, true); + Sphere refFixedSphere(2, 0, Vec3(9,9,14), Vec3(0,0,0), Quat(), 3, iron, false, false, true); SphereID fixedSphere = createSphere( *globalStorage, forest->getBlockStorage(), storageID, 0, Vec3(9,9,14), 3, iron, false, false, true); walberla::id_t fixedSphereID = 0; if (fixedSphere != NULL) fixedSphereID = fixedSphere->getSystemID(); @@ -87,16 +87,16 @@ int main( int argc, char ** argv ) cr.setGlobalLinearAcceleration(Vec3(0, 0, real_c(-9.81))); - checkVitalParameters(refGlobalSphere, globalSphere); + checkVitalParameters(&refGlobalSphere, globalSphere); for (auto it = forest->begin(); it != forest->end(); ++it) { blockforest::Block& block = *(dynamic_cast<blockforest::Block*>(&(*it))); - if (block.getAABB().intersects(refFixedSphere->getAABB())) + if (block.getAABB().intersects(refFixedSphere.getAABB())) { SphereID fixed = static_cast<SphereID> (getBody(*globalStorage, forest->getBlockStorage(), storageID, fixedSphereID)); WALBERLA_ASSERT_NOT_NULLPTR(fixed); - checkVitalParameters(refFixedSphere,fixed); - if (!block.getAABB().contains(refFixedSphere->getPosition())) + checkVitalParameters(&refFixedSphere,fixed); + if (!block.getAABB().contains(refFixedSphere.getPosition())) { WALBERLA_ASSERT(fixed->isRemote()); } @@ -108,17 +108,17 @@ int main( int argc, char ** argv ) syncShadowOwners<BodyTuple>( forest->getBlockForest(), storageID, NULL, real_c(0.0), false); WALBERLA_LOG_PROGRESS_ON_ROOT("*** SIMULATION - END ***"); - refGlobalSphere->setPosition(Vec3(11,11,11)); - checkVitalParameters(refGlobalSphere, globalSphere); + refGlobalSphere.setPosition(Vec3(11,11,11)); + checkVitalParameters(&refGlobalSphere, globalSphere); for (auto it = forest->begin(); it != forest->end(); ++it) { blockforest::Block& block = *(dynamic_cast<blockforest::Block*>(&(*it))); - if (block.getAABB().intersects(refFixedSphere->getAABB())) + if (block.getAABB().intersects(refFixedSphere.getAABB())) { SphereID fixed = static_cast<SphereID> (getBody(*globalStorage, forest->getBlockStorage(), storageID, fixedSphereID)); WALBERLA_ASSERT_NOT_NULLPTR(fixed); - checkVitalParameters(refFixedSphere, fixed); - if (!block.getAABB().contains(refFixedSphere->getPosition())) + checkVitalParameters(&refFixedSphere, fixed); + if (!block.getAABB().contains(refFixedSphere.getPosition())) { WALBERLA_ASSERT(fixed->isRemote()); } diff --git a/tests/pe/BodyIterators.cpp b/tests/pe/BodyIterators.cpp index a14fc38c543ae11787bd3ed28bda4f1ed1f1f803..0dbfcc53cbeb966e45afd28e7fdbb1d36294e8ce 100644 --- a/tests/pe/BodyIterators.cpp +++ b/tests/pe/BodyIterators.cpp @@ -14,7 +14,7 @@ // with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. // //! \file BodyIterators.cpp -//! \author Florian Schornbaum <florian.schornbaum@fau.de> +//! \author Sebastian Eibl <sebastian.eibl@fau.de> // //====================================================================================================================== diff --git a/tests/pe/BodyStorage.cpp b/tests/pe/BodyStorage.cpp index 644f29a1c063de596a9d15081778b2bd23ef784f..498f973944f7d2529ea84072253a4516616104db 100644 --- a/tests/pe/BodyStorage.cpp +++ b/tests/pe/BodyStorage.cpp @@ -54,18 +54,21 @@ int main( int argc, char** argv ) MaterialID iron = Material::find("iron"); { BodyStorage storage; - auto bd1 = new Body1(1, iron); - auto bd2 = new Body2(2, iron); - auto bd3 = new Body2(3, iron); - auto bd4 = new Body2(4, iron); + auto bd1Ptr = std::make_unique<Body1>(1, iron); + auto bd2Ptr = std::make_unique<Body2>(2, iron); + auto bd3Ptr = std::make_unique<Body2>(3, iron); + auto bd4Ptr = std::make_unique<Body2>(4, iron); + + auto bd2 = bd2Ptr.get(); + auto bd3 = bd3Ptr.get(); WALBERLA_CHECK_EQUAL(Body1::refCount, 1); WALBERLA_CHECK_EQUAL(Body2::refCount, 3); - storage.add(bd1); - storage.add(bd2); - storage.add(bd3); - storage.add(bd4); + storage.add(std::move(bd1Ptr)); + storage.add(std::move(bd2Ptr)); + storage.add(std::move(bd3Ptr)); + storage.add(std::move(bd4Ptr)); WALBERLA_CHECK_EQUAL(storage.size(), 4); WALBERLA_CHECK_EQUAL(Body1::refCount, 1); diff --git a/tests/pe/CMakeLists.txt b/tests/pe/CMakeLists.txt index 4cb798ed7bca97708c06190be9e2f298947a8fb3..49002bdc955b67fb6b97361a3a7e38f50e592fa4 100644 --- a/tests/pe/CMakeLists.txt +++ b/tests/pe/CMakeLists.txt @@ -22,7 +22,7 @@ waLBerla_execute_test( NAME PE_CHECKVITALPARAMETERS ) waLBerla_compile_test( NAME PE_COLLISION FILES Collision.cpp DEPENDS core ) waLBerla_execute_test( NAME PE_COLLISION ) -waLBerla_compile_test( NAME PE_COLLISIONTOBIASGJK FILES CollisionTobiasGJK.cpp DEPENDS core ) +waLBerla_compile_test( NAME PE_COLLISIONTOBIASGJK FILES CollisionTobiasGJK.cpp DEPENDS core ) waLBerla_execute_test( NAME PE_COLLISIONTOBIASGJK ) waLBerla_compile_test( NAME PE_CREATEWORLD FILES CreateWorld.cpp DEPENDS core ) diff --git a/tests/pe/Collision.cpp b/tests/pe/Collision.cpp index 98ce1fc4a43f00854911c54a7373f0c86e50cbf8..bd77d39c049c6fd6dc3ec7ad7c629f159afa2615 100644 --- a/tests/pe/Collision.cpp +++ b/tests/pe/Collision.cpp @@ -18,7 +18,6 @@ // //====================================================================================================================== -#include "pe/collision/GJKEPAHelper.h" #include "pe/fcd/AnalyticCollisionDetection.h" #include "pe/utility/BodyCast.h" @@ -31,6 +30,7 @@ #include "pe/rigidbody/Sphere.h" #include "pe/rigidbody/Plane.h" #include "pe/rigidbody/Union.h" +#include "pe/rigidbody/UnionFactory.h" #include "pe/rigidbody/SetBodyTypeIDs.h" #include "pe/Types.h" @@ -125,20 +125,14 @@ void BoxTest() std::vector<Contact> contacts; fcd::AnalyticCollideFunctor< std::vector<Contact> > collideFunc(contacts); - real_t penetrationDepth = real_t(0); - Vec3 contactPoint = Vec3(); - Vec3 contactNormal = Vec3(); - // std::vector<Contact> contacts; // BOX <-> BOX WALBERLA_LOG_INFO("BOX <-> BOX"); - WALBERLA_CHECK( !collideGJK(&b1, &b3, contactPoint, contactNormal, penetrationDepth) ); WALBERLA_CHECK( !collideFunc(&b1, &b3) ); // WALBERLA_LOG_WARNING("contactPoint : " << contactPoint); // WALBERLA_LOG_WARNING("contactNormal : " << contactNormal); // WALBERLA_LOG_WARNING("penetrationDepth: " << penetrationDepth); - WALBERLA_CHECK( collideGJK(&b1, &b2, contactPoint, contactNormal, penetrationDepth) ); WALBERLA_CHECK( collideFunc(&b1, &b2) ); // WALBERLA_LOG_WARNING("contactPoint : " << contactPoint); // WALBERLA_LOG_WARNING("contactNormal : " << contactNormal); @@ -146,29 +140,24 @@ void BoxTest() b4.setPosition( (Vec3(0,0,1) * real_t(sqrt(3)) + Vec3(0,0,1)) * 0.999); - WALBERLA_CHECK( collideGJK(&b1, &b4, contactPoint, contactNormal, penetrationDepth) ); WALBERLA_CHECK( collideFunc(&b1, &b4) ); // WALBERLA_LOG_WARNING("contactPoint : " << contacts.back().getPosition()); // WALBERLA_LOG_WARNING("contactNormal : " << contacts.back().getNormal()); // WALBERLA_LOG_WARNING("penetrationDepth: " << contacts.back().getDistance()); b4.setPosition( (Vec3(0,0,1) * real_t(sqrt(3)) + Vec3(0,0,1)) * 1.001); - WALBERLA_CHECK( !collideGJK(&b1, &b4, contactPoint, contactNormal, penetrationDepth) ); WALBERLA_CHECK( !collideFunc(&b1, &b4) ); b5.setPosition( (Vec3(0,0,1) * real_t(sqrt(3)) + Vec3(0,0,1)) * 0.99); - WALBERLA_CHECK( collideGJK(&b1, &b5, contactPoint, contactNormal, penetrationDepth) ); WALBERLA_CHECK( collideFunc(&b1, &b5) ); // WALBERLA_LOG_WARNING("contactPoint : " << contacts.back().getPosition()); // WALBERLA_LOG_WARNING("contactNormal : " << contacts.back().getNormal()); // WALBERLA_LOG_WARNING("penetrationDepth: " << contacts.back().getDistance()); b5.setPosition( (Vec3(0,0,1) * real_t(sqrt(3)) + Vec3(0,0,1)) * 1.01); - WALBERLA_CHECK( !collideGJK(&b1, &b5, contactPoint, contactNormal, penetrationDepth) ); WALBERLA_CHECK( !collideFunc(&b1, &b5) ); Sphere s1(126, 0, Vec3(real_t(1.5), real_t(1.5), real_t(1.5)), Vec3(0,0,0), Quat(), 1, iron, false, true, false); - WALBERLA_CHECK( collideGJK(&b1, &s1, contactPoint, contactNormal, penetrationDepth) ); WALBERLA_CHECK( collideFunc(&b1, &s1) ); // WALBERLA_LOG_WARNING("contactPoint : " << contactPoint); // WALBERLA_LOG_WARNING("contactNormal : " << contactNormal); @@ -186,13 +175,6 @@ void CapsuleTest() // CAPSULE <-> SPHERE WALBERLA_LOG_INFO("CAPSULE <-> SPHERE"); - sp1.setPosition(real_t(2.9), 0, 0); - WALBERLA_CHECK( collideGJK(&c1, &sp1, contacts) ); -// WALBERLA_LOG_WARNING("contactPoint : " << contacts.at(0).getPosition()); -// WALBERLA_LOG_WARNING("contactNormal : " << contacts.at(0).getNormal()); -// WALBERLA_LOG_WARNING("penetrationDepth: " << contacts.at(0).getDistance()); - sp1.setPosition(real_t(3.1), 0, 0); - WALBERLA_CHECK( !collideGJK(&c1, &sp1, contacts) ); sp1.setPosition(0, real_t(1.9), 0); WALBERLA_CHECK( collideFunc(&c1, &sp1) ); @@ -224,8 +206,6 @@ void CapsuleTest() void CapsuleTest2() { - setMaxGJKIterations(10000); - setEPATolerance(real_t(0.00000001)); const real_t static_cof ( real_t(0.1) / 2 ); // Coefficient of static friction. Roughly 0.85 with high variation depending on surface roughness for low stresses. Note: pe doubles the input coefficient of friction for material-material contacts. const real_t dynamic_cof ( static_cof ); // Coefficient of dynamic friction. Similar to static friction for low speed friction. MaterialID material = createMaterial( "granular", real_t( 1.0 ), 0, static_cof, dynamic_cof, real_t( 0.5 ), 1, 1, 0, 0 ); @@ -239,10 +219,6 @@ void CapsuleTest2() WALBERLA_LOG_DEVEL( c1 ); WALBERLA_LOG_DEVEL( sp1 ); - real_t penetrationDepth = real_t(0); - Vec3 contactPoint = Vec3(); - Vec3 contactNormal = Vec3(); - WALBERLA_LOG_INFO("CAPSULE TEST"); Vec2 distance; distance[0] = (sp1.getPosition() - c1.getPosition())[0]; @@ -250,36 +226,20 @@ void CapsuleTest2() std::cout << std::setprecision(10); WALBERLA_LOG_DEVEL("DISTANCE: " << distance.length()); - WALBERLA_LOG_DEVEL("GJK: " << getMaxGJKIterations()); - WALBERLA_LOG_DEVEL("EPA: " << getEPATolerance() ); - WALBERLA_LOG_DEVEL(" CAPSULE <-> SPHERE (GJK) "); - WALBERLA_LOG_DEVEL( collideGJK(&c1, &sp1, contactPoint, contactNormal, penetrationDepth) ); - WALBERLA_LOG_WARNING("contactPoint : " << contactPoint); - WALBERLA_LOG_WARNING("contactNormal : " << contactNormal); - WALBERLA_LOG_WARNING("penetrationDepth: " << penetrationDepth); - WALBERLA_LOG_DEVEL(" SPHERE <-> CAPSULE (GJK) "); - WALBERLA_LOG_DEVEL( collideGJK(&sp1, &c1, contactPoint, contactNormal, penetrationDepth) ); - WALBERLA_LOG_WARNING("contactPoint : " << contactPoint); - WALBERLA_LOG_WARNING("contactNormal : " << contactNormal); - WALBERLA_LOG_WARNING("penetrationDepth: " << penetrationDepth); WALBERLA_LOG_DEVEL(" SPHERE <-> CAPSULE (ANALYTICAL) "); WALBERLA_LOG_DEVEL( collide(&sp1, &c1, contacts) ); WALBERLA_LOG_WARNING("contactPoint : " << contacts.at(0).getPosition()); WALBERLA_LOG_WARNING("contactNormal : " << contacts.at(0).getNormal()); WALBERLA_LOG_WARNING("penetrationDepth: " << contacts.at(0).getDistance()); - } void UnionTest() { typedef Union< boost::tuple<Sphere> > UnionT; - MaterialID iron = Material::find("iron"); UnionT un1(120, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), false, true, false); UnionT un2(121, 0, Vec3(real_t(1.5),0,0), Vec3(0,0,0), Quat(), false, true, false); - SphereID sp1 = new Sphere(123, 1, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false); - un1.add(sp1); - SphereID sp2 = new Sphere(124, 2, Vec3(real_t(1.5),0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false); - un2.add(sp2); + auto sp1 = createSphere(&un1, 123, Vec3(0,0,0), 1); + auto sp2 = createSphere(&un2, 124, Vec3(real_t(1.5),0,0), 1); std::vector<Contact> contacts; diff --git a/tests/pe/CollisionTobiasGJK.cpp b/tests/pe/CollisionTobiasGJK.cpp index e800d11f80e76aed81568a148406c1e21578716b..46889c1eab92e2fb883173cb525fb324a510e00b 100644 --- a/tests/pe/CollisionTobiasGJK.cpp +++ b/tests/pe/CollisionTobiasGJK.cpp @@ -32,6 +32,7 @@ #include "pe/rigidbody/Sphere.h" #include "pe/rigidbody/Plane.h" #include "pe/rigidbody/Union.h" +#include "pe/rigidbody/UnionFactory.h" #include "pe/rigidbody/Ellipsoid.h" #include "pe/rigidbody/SetBodyTypeIDs.h" @@ -48,7 +49,7 @@ using namespace walberla; using namespace walberla::pe; -typedef boost::tuple<Box, Capsule, Plane, Sphere, Union<boost::tuple<Sphere, Union<boost::tuple<Sphere>>>>, Ellipsoid> BodyTuple ; +typedef boost::tuple<Box, Capsule, Plane, Sphere, Union<boost::tuple<Sphere>>, Union<boost::tuple<Sphere, Union<boost::tuple<Sphere>>>>, Ellipsoid> BodyTuple ; bool gjkEPAcollideHybrid(GeomPrimitive &geom1, GeomPrimitive &geom2, Vec3& normal, Vec3& contactPoint, real_t& penetrationDepth) { @@ -63,6 +64,7 @@ bool gjkEPAcollideHybrid(GeomPrimitive &geom1, GeomPrimitive &geom2, Vec3& norma //2. If collision is possible perform EPA. //std::cerr << "Peforming EPA."; EPA epa; + epa.useSphereOptimization( true ); return epa.doEPAmargin(geom1, geom2, gjk, normal, contactPoint, penetrationDepth, margin); }else{ return false; @@ -354,32 +356,29 @@ void UnionTest(){ Box box(179, 179, Vec3(0,0,0), Vec3(0,0,0), Quat(), Vec3(real_t(10),real_t(2), real_t(10)), iron, false, true, false); - Union<boost::tuple<Sphere>> *unsub = new Union<boost::tuple<Sphere>>(192, 192, Vec3(0,real_t(3.8),0), Vec3(0,0,0), Quat(), false, true, false); + using UnionT = Union<boost::tuple<Sphere>>; + auto unsub = std::make_unique<UnionT>(192, 192, Vec3(0,real_t(3.8),0), Vec3(0,0,0), Quat(), false, true, false); - Sphere sp1( 180, 180, Vec3(-3,real_t(3.8),0), Vec3(0,0,0), Quat(), real_t(3.0) , iron, false, true, false ); - Sphere sp2( 181, 181, Vec3(3,real_t(3.8),0), Vec3(0,0,0), Quat(), real_t(3.0), iron, false, true, false ); - - Sphere sp3( 182, 182, Vec3(0,real_t(6),0), Vec3(0,0,0), Quat(), real_t(3.0), iron, false, true, false ); - unsub->add(&sp1); - unsub->add(&sp2); + auto sp1 = createSphere(unsub.get(), 180, Vec3(-3,real_t(3.8),0), real_t(3.0)); + auto sp2 = createSphere(unsub.get(), 181, Vec3(3,real_t(3.8),0), real_t(3.0)); //Create another union, and add sub union - Union<boost::tuple<Sphere, Union<boost::tuple<Sphere>>>> *un = new Union<boost::tuple<Sphere, Union<boost::tuple<Sphere>>>>(193, 193, Vec3(0, 0, 0), Vec3(0,0,0), Quat(), false, true, false); - un->add(&sp3); - un->add(unsub); + Union<boost::tuple<Sphere, Union<boost::tuple<Sphere>>>> un(193, 193, Vec3(0, 0, 0), Vec3(0,0,0), Quat(), false, true, false); + createSphere(&un, 182, Vec3(0,real_t(6),0), real_t(3.0)); + un.add(std::move(unsub)); PossibleContacts pcs; - pcs.push_back(std::pair<Union<boost::tuple<Sphere,Union<boost::tuple<Sphere>>>>*, Box*>(un, &box)); + pcs.push_back(std::pair<Union<boost::tuple<Sphere,Union<boost::tuple<Sphere>>>>*, Box*>(&un, &box)); Contacts& container = testFCD.generateContacts(pcs); WALBERLA_CHECK(container.size() == 2); Contact &c = container.back(); WALBERLA_LOG_DEVEL( c.getDistance() << " " << c.getNormal() << " " << c.getPosition() ); if(c.getBody1()->getID() == 181) { - checkContact( c, Contact(&sp2, &box, Vec3(real_t(3), real_t(0.9), 0), Vec3(0, 1, 0), real_t(-0.2)), Vec3(0,0,0)); + checkContact( c, Contact(sp2, &box, Vec3(real_t(3), real_t(0.9), 0), Vec3(0, 1, 0), real_t(-0.2)), Vec3(0,0,0)); } else if (c.getBody1()->getID() == 179) { - checkContact( c, Contact(&box, &sp2, Vec3(real_t(3), real_t(0.9), 0), Vec3(0, -1, 0), real_t(-0.2)), Vec3(0,0,0)); + checkContact( c, Contact(&box, sp2, Vec3(real_t(3), real_t(0.9), 0), Vec3(0, -1, 0), real_t(-0.2)), Vec3(0,0,0)); } else { WALBERLA_ABORT("Unknown ID!"); } @@ -389,25 +388,25 @@ void UnionTest(){ c = container.back(); WALBERLA_LOG_DEVEL( c.getDistance() << " " << c.getNormal() << " " << c.getPosition() ); if(c.getBody1()->getID() == 180) { - checkContact( c, Contact(&sp1, &box, Vec3(real_t(-3), real_t(0.9), 0), Vec3(0, 1, 0), real_t(-0.2)), Vec3(0,0,0)); + checkContact( c, Contact(sp1, &box, Vec3(real_t(-3), real_t(0.9), 0), Vec3(0, 1, 0), real_t(-0.2)), Vec3(0,0,0)); } else if (c.getBody1()->getID() == 179) { - checkContact( c, Contact(&box, &sp1, Vec3(real_t(-3), real_t(0.9), 0), Vec3(0, -1, 0), real_t(-0.2)), Vec3(0,0,0)); + checkContact( c, Contact(&box, sp1, Vec3(real_t(-3), real_t(0.9), 0), Vec3(0, -1, 0), real_t(-0.2)), Vec3(0,0,0)); } else { WALBERLA_ABORT("Unknown ID!"); } pcs.clear(); //Vice Versa - pcs.push_back(std::pair<Box*, Union<boost::tuple<Sphere, Union<boost::tuple<Sphere>>>>* >(&box, un)); + pcs.push_back(std::pair<Box*, Union<boost::tuple<Sphere, Union<boost::tuple<Sphere>>>>* >(&box, &un)); container = testFCD.generateContacts(pcs); WALBERLA_CHECK(container.size() == 2); c = container.back(); WALBERLA_LOG_DEVEL( c.getDistance() << " " << c.getNormal() << " " << c.getPosition() ); if(c.getBody1()->getID() == 181) { - checkContact( c, Contact(&sp2, &box, Vec3(real_t(3), real_t(0.9), 0), Vec3(0, 1, 0), real_t(-0.2)), Vec3(0,0,0)); + checkContact( c, Contact(sp2, &box, Vec3(real_t(3), real_t(0.9), 0), Vec3(0, 1, 0), real_t(-0.2)), Vec3(0,0,0)); } else if (c.getBody1()->getID() == 179) { - checkContact( c, Contact(&box, &sp2, Vec3(real_t(3), real_t(0.9), 0), Vec3(0, -1, 0), real_t(-0.2)), Vec3(0,0,0)); + checkContact( c, Contact(&box, sp2, Vec3(real_t(3), real_t(0.9), 0), Vec3(0, -1, 0), real_t(-0.2)), Vec3(0,0,0)); } else { WALBERLA_ABORT("Unknown ID!"); } @@ -416,9 +415,9 @@ void UnionTest(){ c = container.back(); WALBERLA_LOG_DEVEL( c.getDistance() << " " << c.getNormal() << " " << c.getPosition() ); if(c.getBody1()->getID() == 180) { - checkContact( c, Contact(&sp1, &box, Vec3(real_t(-3), real_t(0.9), 0), Vec3(0, 1, 0), real_t(-0.2)), Vec3(0,0,0)); + checkContact( c, Contact(sp1, &box, Vec3(real_t(-3), real_t(0.9), 0), Vec3(0, 1, 0), real_t(-0.2)), Vec3(0,0,0)); } else if (c.getBody1()->getID() == 179) { - checkContact( c, Contact(&box, &sp1, Vec3(real_t(-3), real_t(0.9), 0), Vec3(0, -1, 0), real_t(-0.2)), Vec3(0,0,0)); + checkContact( c, Contact(&box, sp1, Vec3(real_t(-3), real_t(0.9), 0), Vec3(0, -1, 0), real_t(-0.2)), Vec3(0,0,0)); } else { WALBERLA_ABORT("Unknown ID!"); } diff --git a/tests/pe/DeleteBody.cpp b/tests/pe/DeleteBody.cpp index 64f03d42a807a89b5cce96903acf13ee7fe5220d..a37e73bff82f8443dc943da092bee612795d60ad 100644 --- a/tests/pe/DeleteBody.cpp +++ b/tests/pe/DeleteBody.cpp @@ -31,6 +31,8 @@ #include "core/debug/TestSubsystem.h" #include "core/math/Random.h" +#include <functional> + using namespace walberla; using namespace walberla::pe; @@ -83,10 +85,10 @@ int main( int argc, char** argv ) std::function<void(void)> syncCall; if (!syncShadowOwners) { - syncCall = boost::bind( pe::syncNextNeighbors<BodyTuple>, boost::ref(forest->getBlockForest()), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false ); + syncCall = std::bind( pe::syncNextNeighbors<BodyTuple>, std::ref(forest->getBlockForest()), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false ); } else { - syncCall = boost::bind( pe::syncShadowOwners<BodyTuple>, boost::ref(forest->getBlockForest()), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false ); + syncCall = std::bind( pe::syncShadowOwners<BodyTuple>, std::ref(forest->getBlockForest()), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false ); } pe::createSphere(*globalBodyStorage, forest->getBlockStorage(), storageID, 0, Vec3(5,5,5), 2); diff --git a/tests/pe/ForceSync.cpp b/tests/pe/ForceSync.cpp index f0901d1b7039d9082dd6ed3569af9bf364d72f40..b97d408077ded3ce50672eddca66ff49b0bc35a0 100644 --- a/tests/pe/ForceSync.cpp +++ b/tests/pe/ForceSync.cpp @@ -98,12 +98,12 @@ int main( int argc, char ** argv ) for (auto bodyIt = localStorage.begin(); bodyIt != localStorage.end(); ++bodyIt) { - BodyID b = *bodyIt; + BodyID b = bodyIt.getBodyID(); b->addForce( Vec3(1,0,0) ); } for (auto bodyIt = shadowStorage.begin(); bodyIt != shadowStorage.end(); ++bodyIt) { - BodyID b = *bodyIt; + BodyID b = bodyIt.getBodyID(); b->addForce( Vec3(0,1,0) ); } } @@ -127,12 +127,12 @@ int main( int argc, char ** argv ) // for (auto bodyIt = localStorage.begin(); bodyIt != localStorage.end(); ++bodyIt) // { -// BodyID b = *bodyIt; +// BodyID b = bodyIt.getBodyID(); // WALBERLA_LOG_DEVEL("LOCAL\n" << b << "\nForce: " << b->getForce()); // } // for (auto bodyIt = shadowStorage.begin(); bodyIt != shadowStorage.end(); ++bodyIt) // { -// BodyID b = *bodyIt; +// BodyID b = bodyIt.getBodyID(); // WALBERLA_LOG_DEVEL("SHADOW\n" << b << "\nForce: " << b->getForce()); // } // } diff --git a/tests/pe/HCSITS.cpp b/tests/pe/HCSITS.cpp index 3a133974f2ed1cf861dabad3e002a799728f31ea..c5e3a2d742e0d058448270ba9e285a003df6a6b5 100644 --- a/tests/pe/HCSITS.cpp +++ b/tests/pe/HCSITS.cpp @@ -93,6 +93,10 @@ void normalReactionTest(cr::HCSITS& cr, SphereID sp) cr.timestep( real_c( real_t(1.0) ) ); WALBERLA_CHECK_FLOAT_EQUAL( sp->getPosition() , Vec3(5,5,real_t(6.1)) ); WALBERLA_CHECK_FLOAT_EQUAL( sp->getLinearVel(), Vec3(0,0,real_t(-0.1)) ); + + cr.timestep( real_c( real_t(1.0) ) ); + WALBERLA_CHECK_FLOAT_EQUAL( sp->getPosition() , Vec3(5,5,real_t(6.1)) ); + WALBERLA_CHECK_FLOAT_EQUAL( sp->getLinearVel(), Vec3(0,0,real_t(0)) ); contactThreshold = Thresholds<real_t>::contactThreshold(); } diff --git a/tests/pe/HashGrids.cpp b/tests/pe/HashGrids.cpp index a1790653be79c8c55fb3a8edab2b760371948bcb..7b203cbe8e0baf7173e7d4f3ee231f2996d883b9 100644 --- a/tests/pe/HashGrids.cpp +++ b/tests/pe/HashGrids.cpp @@ -115,7 +115,8 @@ int main( int argc, char** argv ) iron, true, false, true); syncShadowOwners<BodyTuple>( forest->getBlockForest(), storageID); - for (int step=0; step < 100; ++step){ + for (int step=0; step < 100; ++step) + { cr( real_c(0.1) ); syncShadowOwners<BodyTuple>( forest->getBlockForest(), storageID); diff --git a/tests/pe/Marshalling.cpp b/tests/pe/Marshalling.cpp index 30da9d3be10fbad20a2e545dbfa915a85a988ac0..985269bd619ad65d799ffc62efb6524deefa82e1 100644 --- a/tests/pe/Marshalling.cpp +++ b/tests/pe/Marshalling.cpp @@ -41,11 +41,14 @@ using namespace walberla::pe::communication; typedef boost::tuple<Sphere> UnionTypeTuple; typedef Union< UnionTypeTuple > UnionT; typedef UnionT* UnionID; +typedef std::unique_ptr<UnionT> UnionPtr; typedef boost::tuple<Box, Capsule, Sphere, Squirmer, UnionT, Ellipsoid> BodyTuple ; void testBox() { + WALBERLA_LOG_INFO_ON_ROOT("*** testBox ***"); + MaterialID iron = Material::find("iron"); Box b1(759846, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), Vec3(1,2,3), iron, false, true, false); @@ -56,7 +59,8 @@ void testBox() MarshalDynamically<BodyTuple>::execute(sb, b1); mpi::RecvBuffer rb(sb); - BoxID b2 = static_cast<BoxID> (UnmarshalDynamically<BodyTuple>::execute(rb, Box::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)))); + auto bPtr = UnmarshalDynamically<BodyTuple>::execute(rb, Box::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100))); + BoxID b2 = static_cast<BoxID>(bPtr.get()); WALBERLA_CHECK_FLOAT_EQUAL(b1.getPosition(), b2->getPosition()); WALBERLA_CHECK_FLOAT_EQUAL(b1.getLinearVel(), b2->getLinearVel()); @@ -68,6 +72,8 @@ void testBox() void testCapsule() { + WALBERLA_LOG_INFO_ON_ROOT("*** testCapsule ***"); + MaterialID iron = Material::find("iron"); Capsule c1(759846, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), 5, 7, iron, false, false, false); @@ -78,7 +84,8 @@ void testCapsule() MarshalDynamically<BodyTuple>::execute(sb, c1); mpi::RecvBuffer rb(sb); - CapsuleID c2 = static_cast<CapsuleID> (UnmarshalDynamically<BodyTuple>::execute(rb, Capsule::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)))); + auto cPtr = UnmarshalDynamically<BodyTuple>::execute(rb, Capsule::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100))); + CapsuleID c2 = static_cast<CapsuleID> (cPtr.get()); WALBERLA_CHECK_FLOAT_EQUAL(c1.getPosition(), c2->getPosition()); WALBERLA_CHECK_FLOAT_EQUAL(c1.getLinearVel(), c2->getLinearVel()); @@ -91,6 +98,8 @@ void testCapsule() void testSphere() { + WALBERLA_LOG_INFO_ON_ROOT("*** testSphere ***"); + MaterialID iron = Material::find("iron"); Sphere s1(759846, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), 5, iron, false, false, false); @@ -101,7 +110,8 @@ void testSphere() MarshalDynamically<BodyTuple>::execute(sb, s1); mpi::RecvBuffer rb(sb); - SphereID s2 = static_cast<SphereID> (UnmarshalDynamically<BodyTuple>::execute(rb, Sphere::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)))); + auto sPtr = UnmarshalDynamically<BodyTuple>::execute(rb, Sphere::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100))); + SphereID s2 = static_cast<SphereID> (sPtr.get()); WALBERLA_CHECK_FLOAT_EQUAL(s1.getPosition(), s2->getPosition()); WALBERLA_CHECK_FLOAT_EQUAL(s1.getLinearVel(), s2->getLinearVel()); @@ -113,6 +123,8 @@ void testSphere() void testSquirmer() { + WALBERLA_LOG_INFO_ON_ROOT("*** testSquirmer ***"); + MaterialID iron = Material::find("iron"); Squirmer s1(759846, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), real_c(5), real_c(0.1), real_c(4.93), iron, false, false, false); @@ -123,7 +135,8 @@ void testSquirmer() MarshalDynamically<BodyTuple>::execute(sb, s1); mpi::RecvBuffer rb(sb); - SquirmerID s2 = static_cast<SquirmerID> (UnmarshalDynamically<BodyTuple>::execute(rb, Squirmer::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)))); + auto sPtr = UnmarshalDynamically<BodyTuple>::execute(rb, Squirmer::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100))); + SquirmerID s2 = static_cast<SquirmerID> (sPtr.get()); WALBERLA_CHECK_FLOAT_EQUAL(s1.getSquirmerVelocity(), s2->getSquirmerVelocity()); WALBERLA_CHECK_FLOAT_EQUAL(s1.getSquirmerBeta(), s2->getSquirmerBeta()); @@ -131,6 +144,8 @@ void testSquirmer() void testEllipsoid() { + WALBERLA_LOG_INFO_ON_ROOT("*** testEllipsoid ***"); + MaterialID iron = Material::find("iron"); Ellipsoid e1(759847, 1234795, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), Vec3(3,1,5), iron, false, false, false); @@ -141,7 +156,8 @@ void testEllipsoid() MarshalDynamically<BodyTuple>::execute(sb, e1); mpi::RecvBuffer rb(sb); - EllipsoidID e2 = static_cast<EllipsoidID> (UnmarshalDynamically<BodyTuple>::execute(rb, Ellipsoid::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)))); + auto ePtr = UnmarshalDynamically<BodyTuple>::execute(rb, Ellipsoid::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100))); + EllipsoidID e2 = static_cast<EllipsoidID>(ePtr.get()); WALBERLA_CHECK_FLOAT_EQUAL(e1.getPosition(), e2->getPosition()); WALBERLA_CHECK_FLOAT_EQUAL(e1.getLinearVel(), e2->getLinearVel()); @@ -153,6 +169,7 @@ void testEllipsoid() void testUnion() { + WALBERLA_LOG_INFO_ON_ROOT("*** testUnion ***"); UnionT u1(159, 423, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), false, false, false); SphereID s11 = createSphere< UnionTypeTuple >(&u1, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), 2); SphereID s21 = createSphere< UnionTypeTuple >(&u1, 4567789, Vec3(real_c(3), real_c(2), real_c(3)), real_c(1.5)); @@ -163,15 +180,16 @@ void testUnion() MarshalDynamically<BodyTuple>::execute(sb, u1); mpi::RecvBuffer rb(sb); - UnionID u2 = static_cast<UnionID> (UnmarshalDynamically<BodyTuple>::execute(rb, UnionT::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)))); + auto uPtr = UnmarshalDynamically<BodyTuple>::execute(rb, UnionT::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100))); + UnionID u2 = static_cast<UnionID>(uPtr.get()); WALBERLA_CHECK_NOT_NULLPTR( u2 ); WALBERLA_CHECK_EQUAL(u1.size(), 2); WALBERLA_CHECK_EQUAL(u1.size(), u2->size()); //getting spheres of second union - SphereID s12 = static_cast<SphereID> (*(u2->begin())); - SphereID s22 = static_cast<SphereID> (*(++(u2->begin()))); + SphereID s12 = static_cast<SphereID> (u2->begin().getBodyID()); + SphereID s22 = static_cast<SphereID> ((++(u2->begin())).getBodyID()); WALBERLA_CHECK_UNEQUAL( s12, s22 ); WALBERLA_CHECK_FLOAT_EQUAL( s11->getPosition(), s12->getPosition()); diff --git a/tests/pe/MinMaxRefinement.cpp b/tests/pe/MinMaxRefinement.cpp index 458052c0e4f1853e3ab03b8f45e91c040915699e..3c13d4cfbc7fc6aa974a9cb6f0688e98d813965c 100644 --- a/tests/pe/MinMaxRefinement.cpp +++ b/tests/pe/MinMaxRefinement.cpp @@ -144,7 +144,7 @@ int main( int argc, char ** argv ) ccd->reloadBodies(); } - WALBERLA_CHECK_EQUAL( blockforest.size(), mpi::MPIManager::instance()->worldRank() == 6 ? 1 : 0); + WALBERLA_CHECK_EQUAL( blockforest.size(), mpi::MPIManager::instance()->worldRank() == 0 ? 1 : 0); WALBERLA_LOG_DEVEL( infoCollection->size() ); for (unsigned int i = 0; i < 30; ++i) diff --git a/tests/pe/ParallelEquivalence.cpp b/tests/pe/ParallelEquivalence.cpp index 6a211cd6739ad9613e682832b7269d9d5184531a..03aac6f6fa2f73fdc69422287f9dc6e1a45504cf 100644 --- a/tests/pe/ParallelEquivalence.cpp +++ b/tests/pe/ParallelEquivalence.cpp @@ -157,7 +157,7 @@ void sim(shared_ptr< StructuredBlockForest > forest, std::vector<BodyData>& res, BodyStorage& localStorage = (*storage)[0]; for (auto bodyIt = localStorage.begin(); bodyIt != localStorage.end(); ++bodyIt) { - BodyID b = *bodyIt; + BodyID b = bodyIt.getBodyID(); res.push_back(BodyData(b->getID(), b->getPosition(), b->getLinearVel())); } } diff --git a/tests/pe/RigidBody.cpp b/tests/pe/RigidBody.cpp index 58926892dfa4786e5baaa3a9413bbf04df96390c..ad3e0facb2e5fb3900fccbc4c042b5a341640c1c 100644 --- a/tests/pe/RigidBody.cpp +++ b/tests/pe/RigidBody.cpp @@ -39,10 +39,6 @@ void move( BodyStorage& storage, real_t dt ) WALBERLA_ASSERT( it->checkInvariants(), "Invalid capsule state detected" ); WALBERLA_ASSERT( !it->hasSuperBody(), "Invalid superordinate body detected" ); - // Resetting the contact node and removing all attached contacts -// it->resetNode(); - it->clearContacts(); - // Moving the capsule according to the acting forces (don't move a sleeping body) if( it->isAwake() ) { if( !it->hasInfiniteMass() ) { @@ -86,10 +82,10 @@ void move( BodyStorage& storage, real_t dt ) void checkRotationFunctions() { MaterialID iron = Material::find("iron"); - auto sp1 = shared_ptr<Sphere>( new Sphere(0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false) ); - auto sp2 = shared_ptr<Sphere>( new Sphere(0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false) ); - auto sp3 = shared_ptr<Sphere>( new Sphere(0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false) ); - auto sp4 = shared_ptr<Sphere>( new Sphere(0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false) ); + auto sp1 = std::make_shared<Sphere>( 0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false ); + auto sp2 = std::make_shared<Sphere>( 0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false ); + auto sp3 = std::make_shared<Sphere>( 0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false ); + auto sp4 = std::make_shared<Sphere>( 0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false ); sp1->rotate( 1, 0, 0, math::M_PI * real_t(0.5)); sp1->rotate( 0, 1, 0, math::M_PI * real_t(0.5)); @@ -125,7 +121,7 @@ void checkRotationFunctions() void checkPointFunctions() { MaterialID iron = Material::find("iron"); - auto sp1 = shared_ptr<Sphere>( new Sphere(0, 0, Vec3(10,10,10), Vec3(0,0,0), Quat(), 1, iron, false, true, false) ); + auto sp1 = std::make_shared<Sphere>( 0, 0, Vec3(10,10,10), Vec3(0,0,0), Quat(), 1, iron, false, true, false ); WALBERLA_CHECK( sp1->containsPoint( 10, 10, 10 ) ); WALBERLA_CHECK( sp1->containsPoint( real_c(10.9), 10, 10 ) ); @@ -152,8 +148,8 @@ int main( int argc, char** argv ) MaterialID iron = Material::find("iron"); BodyStorage storage; - SphereID sphere = new Sphere(0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false); - storage.add(sphere); + SpherePtr spPtr = std::make_unique<Sphere>(0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false); + SphereID sphere = static_cast<SphereID>(&storage.add(std::move(spPtr))); Vec3 x0 = Vec3(-2,2,0); Vec3 v0 = Vec3(-1,-1,1); diff --git a/tests/pe/ShadowCopy.cpp b/tests/pe/ShadowCopy.cpp index cbd4958e34ede91c698393f37f42633925f15abc..8c5dba7c4ad95888979f9b6c88f6109fc763d475 100644 --- a/tests/pe/ShadowCopy.cpp +++ b/tests/pe/ShadowCopy.cpp @@ -19,6 +19,7 @@ //====================================================================================================================== #include "pe/basic.h" +#include "pe/rigidbody/UnionFactory.h" #include "pe/utility/GetBody.h" #include "pe/utility/DestroyBody.h" @@ -28,6 +29,8 @@ #include "core/debug/TestSubsystem.h" +#include <functional> + using namespace walberla; using namespace walberla::pe; @@ -65,10 +68,10 @@ int main( int argc, char** argv ) std::function<void(void)> syncCall; if (!syncShadowOwners) { - syncCall = boost::bind( pe::syncNextNeighbors<BodyTuple>, boost::ref(forest->getBlockForest()), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false ); + syncCall = std::bind( pe::syncNextNeighbors<BodyTuple>, std::ref(forest->getBlockForest()), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false ); } else { - syncCall = boost::bind( pe::syncShadowOwners<BodyTuple>, boost::ref(forest->getBlockForest()), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false ); + syncCall = std::bind( pe::syncShadowOwners<BodyTuple>, std::ref(forest->getBlockForest()), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false ); } WALBERLA_LOG_PROGRESS_ON_ROOT( " *** SPHERE *** "); @@ -93,12 +96,9 @@ int main( int argc, char** argv ) destroyBodyBySID( *globalBodyStorage, forest->getBlockStorage(), storageID, sid ); WALBERLA_LOG_PROGRESS_ON_ROOT( " *** UNION *** "); - MaterialID iron = Material::find("iron"); UnionT* un = createUnion< boost::tuple<Sphere> >( *globalBodyStorage, forest->getBlockStorage(), storageID, 0, Vec3(2,2,2) ); - SphereID sp1 = new Sphere( 10, 0, Vec3(real_t(4.9),2,2), Vec3(0,0,0), Quat(), real_t(1) , iron, false, true, false ); - SphereID sp2 = new Sphere( 11, 0, Vec3(3,2,2) , Vec3(0,0,0), Quat(), real_t(1.5), iron, false, true, false ); - un->add(sp1); - un->add(sp2); + auto sp1 = createSphere(un, 10, Vec3(real_t(4.9),2,2), real_t(1)); + auto sp2 = createSphere(un, 11, Vec3(3,2,2), real_t(1.5)); un->setPosition( Vec3( real_t(4.9), 2, 2) ); auto relPosSp1 = sp1->getRelPosition(); auto relPosSp2 = sp2->getRelPosition(); @@ -111,8 +111,8 @@ int main( int argc, char** argv ) syncCall(); un = static_cast<UnionT*> (getBody( *globalBodyStorage, forest->getBlockStorage(), storageID, sid, StorageSelect::LOCAL )); - sp1 = static_cast<SphereID> (*(un->begin())); - sp2 = static_cast<SphereID> (*(++(un->begin()))); + sp1 = static_cast<SphereID> (un->begin().getBodyID()); + sp2 = static_cast<SphereID> ((++(un->begin())).getBodyID()); WALBERLA_CHECK_NOT_NULLPTR(sp1); WALBERLA_CHECK_NOT_NULLPTR(sp2); WALBERLA_CHECK_EQUAL( sp1->getTypeID(), Sphere::getStaticTypeID() ); @@ -150,8 +150,8 @@ int main( int argc, char** argv ) posUnion = Vec3(real_t(0.9),2,2); un = static_cast<UnionT*> (getBody( *globalBodyStorage, forest->getBlockStorage(), storageID, sid, StorageSelect::LOCAL )); - sp1 = static_cast<SphereID> (*(un->begin())); - sp2 = static_cast<SphereID> (*(++(un->begin()))); + sp1 = static_cast<SphereID> (un->begin().getBodyID()); + sp2 = static_cast<SphereID> ((++(un->begin())).getBodyID()); WALBERLA_CHECK_NOT_NULLPTR(sp1); WALBERLA_CHECK_NOT_NULLPTR(sp2); WALBERLA_CHECK_EQUAL( sp1->getTypeID(), Sphere::getStaticTypeID() ); diff --git a/tests/pe/SimpleCCD.cpp b/tests/pe/SimpleCCD.cpp index cd0095811a842b11aa2d3bc2d54d95c60d93a0b9..527a846383cb8931c3215e5a16352093918f4699 100644 --- a/tests/pe/SimpleCCD.cpp +++ b/tests/pe/SimpleCCD.cpp @@ -19,18 +19,19 @@ //====================================================================================================================== #include "pe/Materials.h" -#include "pe/rigidbody/Sphere.h" #include "pe/Types.h" #include "pe/rigidbody/BodyStorage.h" +#include "pe/rigidbody/SetBodyTypeIDs.h" +#include "pe/rigidbody/Sphere.h" #include "pe/ccd/SimpleCCD.h" #include "pe/ccd/HashGrids.h" #include "pe/fcd/SimpleFCD.h" -#include "core/DataTypes.h" +#include "core/DataTypes.h" +#include "core/UniqueID.h" #include "core/timing/TimingPool.h" #include "core/debug/TestSubsystem.h" #include "core/math/Random.h" -#include "core/UniqueID.h" using namespace walberla; using namespace walberla::pe; @@ -43,6 +44,8 @@ int main( int argc, char** argv ) walberla::MPIManager::instance()->initializeMPI( &argc, &argv ); + SetBodyTypeIDs<BodyTuple>::execute(); + MaterialID iron = Material::find("iron"); BodyStorage globalStorage; @@ -57,7 +60,7 @@ int main( int argc, char** argv ) math::seedRandomGenerator(1337); for (uint_t i = 0; i < 100; ++i) - storage[0].add( new Sphere(UniqueID<Sphere>::createGlobal(), 0, Vec3( math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10))), Vec3(0,0,0), Quat(), 1, iron, false, false, false) ); + storage[0].add( std::make_unique<Sphere>(UniqueID<Sphere>::createGlobal(), 0, Vec3( math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10))), Vec3(0,0,0), Quat(), 1, iron, false, false, false) ); sccd.generatePossibleContacts(); @@ -67,7 +70,7 @@ int main( int argc, char** argv ) WALBERLA_LOG_DEVEL( s_fcd.getContacts().size() ); - BodyID bd = *(storage[0].begin() + 5); + BodyID bd = (storage[0].begin() + 5).getBodyID(); storage[0].remove( bd ); sccd.generatePossibleContacts(); @@ -81,14 +84,14 @@ int main( int argc, char** argv ) bs.clear(); - bs.add( new Sphere(UniqueID<Sphere>::createGlobal(), 0, Vec3( math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10))), Vec3(0,0,0), Quat(), 1, iron, false, false, false) ); + bs.add( std::make_unique<Sphere>(UniqueID<Sphere>::createGlobal(), 0, Vec3( math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10))), Vec3(0,0,0), Quat(), 1, iron, false, false, false) ); WcTimingPool pool; for (int runs = 0; runs < 10; ++runs) { auto oldSize = bs.size(); for (uint_t i = 0; i < oldSize; ++i) - bs.add( new Sphere(UniqueID<Sphere>::createGlobal(), 0, Vec3( math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10))), Vec3(0,0,0), Quat(), 0.5, iron, false, false, false) ); + bs.add( std::make_unique<Sphere>(UniqueID<Sphere>::createGlobal(), 0, Vec3( math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10))), Vec3(0,0,0), Quat(), 0.5, iron, false, false, false) ); pool["SCCD"].start(); sccd.generatePossibleContacts(); pool["SCCD"].end(); diff --git a/tests/pe/SyncEquivalence.cpp b/tests/pe/SyncEquivalence.cpp index c311e1d6728ebd00a11b86451b0a8b208ef94d33..6afd4f8670bc0ceeac07567021c9581516887241 100644 --- a/tests/pe/SyncEquivalence.cpp +++ b/tests/pe/SyncEquivalence.cpp @@ -115,7 +115,7 @@ void createSimulation(math::AABB& simulationDomain, info.ccdID = info.forest->addBlockData(ccd::createHashGridsDataHandling( info.globalBodyStorage, info.storageID ), "CCD"); info.fcdID = info.forest->addBlockData(fcd::createGenericFCDDataHandling<BodyTuple, fcd::AnalyticCollideFunctor>(), "FCD"); - info.cr = shared_ptr<cr::ICR>(new cr::HCSITS(info.globalBodyStorage, info.forest->getBlockStoragePointer(), info.storageID, info.ccdID, info.fcdID) ); + info.cr = std::make_shared<cr::HCSITS>(info.globalBodyStorage, info.forest->getBlockStoragePointer(), info.storageID, info.ccdID, info.fcdID ); int numParticles = int_c(0); @@ -227,7 +227,7 @@ int main( int argc, char ** argv ) WALBERLA_CHECK_EQUAL(shadowOwnersIt1->blockID_, shadowOwnersIt2->blockID_); } - checkVitalParameters( static_cast<SphereID>(*bodyIt1), static_cast<SphereID>(*bodyIt2) ); + checkVitalParameters( static_cast<SphereID>(bodyIt1.getBodyID()), static_cast<SphereID>(bodyIt2.getBodyID()) ); } } diff --git a/tests/pe/Synchronization.cpp b/tests/pe/Synchronization.cpp index c8ad534ffe4d84a832ba4e4986eacc1e62d72501..17d33c41be16009ad7a04fd91239f9f76ccdaaa1 100644 --- a/tests/pe/Synchronization.cpp +++ b/tests/pe/Synchronization.cpp @@ -39,7 +39,7 @@ using namespace walberla::blockforest; typedef boost::tuple<Sphere> BodyTuple ; -void checkSphere(StructuredBlockForest& forest, BlockDataID storageID, walberla::id_t sid, SphereID ref, const Vec3& newPos) +void checkSphere(StructuredBlockForest& forest, BlockDataID storageID, walberla::id_t sid, Sphere& ref, const Vec3& newPos) { for (auto it = forest.begin(); it != forest.end(); ++it) { @@ -47,37 +47,37 @@ void checkSphere(StructuredBlockForest& forest, BlockDataID storageID, walberla: Storage& storage = *(block.getData<Storage>(storageID)); BodyStorage& shadowStorage = storage[1]; - if (block.getAABB().contains( ref->getPosition() )) + if (block.getAABB().contains( ref.getPosition() )) { - WALBERLA_CHECK_EQUAL( storage[StorageType::LOCAL].size(), 1, "pos: " << ref->getPosition() << "\nradius: " << ref->getRadius() << "\ndomain: " << block.getAABB() ); - WALBERLA_CHECK_EQUAL( shadowStorage.size(), 0, "pos: " << ref->getPosition() << "\nradius: " << ref->getRadius() << "\ndomain: " << block.getAABB() ); - SphereID bd = static_cast<SphereID> (*(storage[StorageType::LOCAL].find( sid ))); + WALBERLA_CHECK_EQUAL( storage[StorageType::LOCAL].size(), 1, "pos: " << ref.getPosition() << "\nradius: " << ref.getRadius() << "\ndomain: " << block.getAABB() ); + WALBERLA_CHECK_EQUAL( shadowStorage.size(), 0, "pos: " << ref.getPosition() << "\nradius: " << ref.getRadius() << "\ndomain: " << block.getAABB() ); + SphereID bd = static_cast<SphereID> (storage[StorageType::LOCAL].find( sid ).getBodyID()); WALBERLA_CHECK_NOT_NULLPTR(bd); - checkVitalParameters(bd, ref); + checkVitalParameters(bd, &ref); WALBERLA_LOG_DEVEL("#shadows: " << bd->MPITrait.sizeShadowOwners() << " #block states set: " << bd->MPITrait.getBlockStateSize() << "\nowner domain: " << block.getAABB() << "\nowner: " << bd->MPITrait.getOwner()); bd->setPosition( newPos ); - } else if (forest.periodicIntersect(block.getAABB(), ref->getAABB()) ) + } else if (forest.periodicIntersect(block.getAABB(), ref.getAABB()) ) { - WALBERLA_CHECK_EQUAL( storage[StorageType::LOCAL].size(), 0, "pos: " << ref->getPosition() << "\nradius: " << ref->getRadius() << "\ndomain: " << block.getAABB() ); - WALBERLA_CHECK_EQUAL( shadowStorage.size(), 1, "pos: " << ref->getPosition() << "\nradius: " << ref->getRadius() << "\ndomain: " << block.getAABB() ); - SphereID bd = static_cast<SphereID> (*(shadowStorage.find( sid ))); + WALBERLA_CHECK_EQUAL( storage[StorageType::LOCAL].size(), 0, "pos: " << ref.getPosition() << "\nradius: " << ref.getRadius() << "\ndomain: " << block.getAABB() ); + WALBERLA_CHECK_EQUAL( shadowStorage.size(), 1, "pos: " << ref.getPosition() << "\nradius: " << ref.getRadius() << "\ndomain: " << block.getAABB() ); + SphereID bd = static_cast<SphereID> (shadowStorage.find( sid ).getBodyID()); WALBERLA_CHECK_NOT_NULLPTR(bd); - auto backupPos =ref->getPosition(); - auto correctedPos = ref->getPosition(); + auto backupPos =ref.getPosition(); + auto correctedPos = ref.getPosition(); pe::communication::correctBodyPosition(forest.getDomain(), block.getAABB().center(), correctedPos); - ref->setPosition(correctedPos); - checkVitalParameters(bd, ref); - ref->setPosition(backupPos); + ref.setPosition(correctedPos); + checkVitalParameters(bd, &ref); + ref.setPosition(backupPos); } else { - WALBERLA_CHECK_EQUAL( storage[StorageType::LOCAL].size(), 0, "pos: " << ref->getPosition() << "\nradius: " << ref->getRadius() << "\ndomain: " << block.getAABB() ); - WALBERLA_CHECK_EQUAL( shadowStorage.size(), 0, "pos: " << ref->getPosition() << "\nradius: " << ref->getRadius() << "\ndomain: " << block.getAABB() ); + WALBERLA_CHECK_EQUAL( storage[StorageType::LOCAL].size(), 0, "pos: " << ref.getPosition() << "\nradius: " << ref.getRadius() << "\ndomain: " << block.getAABB() ); + WALBERLA_CHECK_EQUAL( shadowStorage.size(), 0, "pos: " << ref.getPosition() << "\nradius: " << ref.getRadius() << "\ndomain: " << block.getAABB() ); } } - WALBERLA_LOG_PROGRESS("checked pos: " << ref->getPosition() << " | new pos: " << newPos); + WALBERLA_LOG_PROGRESS("checked pos: " << ref.getPosition() << " | new pos: " << newPos); auto temp = newPos; forest.mapToPeriodicDomain(temp); - ref->setPosition(temp); + ref.setPosition(temp); } int main( int argc, char ** argv ) @@ -117,9 +117,9 @@ int main( int argc, char ** argv ) MaterialID iron = Material::find("iron"); walberla::id_t sid = 123; - SphereID refSphere = new Sphere(1, 0, Vec3(15, 15, 15), Vec3(0,0,0), Quat(), 3, iron, false, true, false); - refSphere->setLinearVel(4, 5, 6); - refSphere->setAngularVel( 1, 2, 3); + Sphere refSphere(1, 0, Vec3(15, 15, 15), Vec3(0,0,0), Quat(), 3, iron, false, true, false); + refSphere.setLinearVel(4, 5, 6); + refSphere.setAngularVel( 1, 2, 3); Vec3 gpos = Vec3(15, 15, 15); SphereID sphere = createSphere( globalStorage, forest->getBlockStorage(), storageID, 0, gpos, 3); diff --git a/tests/pe/SynchronizationLargeBody.cpp b/tests/pe/SynchronizationLargeBody.cpp index ab7123da2b10ac22081e798867e8584315fdc9d7..6bf99cc4700baa403698e23964c9a73139c14953 100644 --- a/tests/pe/SynchronizationLargeBody.cpp +++ b/tests/pe/SynchronizationLargeBody.cpp @@ -51,7 +51,7 @@ void checkSphere(StructuredBlockForest& forest, BlockDataID storageID, walberla: { WALBERLA_CHECK_EQUAL( storage[StorageType::LOCAL].size(), 1 ); WALBERLA_CHECK_EQUAL( shadowStorage.size(), 0 ); - SphereID bd = static_cast<SphereID> (*(storage[0].find( sid ))); + SphereID bd = static_cast<SphereID> (storage[0].find( sid ).getBodyID()); WALBERLA_CHECK_NOT_NULLPTR(bd); checkVitalParameters(bd, ref); bd->setPosition( newPos ); @@ -59,7 +59,7 @@ void checkSphere(StructuredBlockForest& forest, BlockDataID storageID, walberla: { WALBERLA_CHECK_EQUAL( storage[0].size(), 0 ); WALBERLA_CHECK_EQUAL( shadowStorage.size(), 1 ); - SphereID bd = static_cast<SphereID> (*(shadowStorage.find( sid ))); + SphereID bd = static_cast<SphereID> (shadowStorage.find( sid ).getBodyID()); WALBERLA_CHECK_NOT_NULLPTR(bd); auto backupPos =ref->getPosition(); auto correctedPos = ref->getPosition(); @@ -92,7 +92,7 @@ void checkSphere(StructuredBlockForest& forest, BlockDataID storageID, walberla: { WALBERLA_CHECK_EQUAL( storage[StorageType::LOCAL].size(), 1 ); WALBERLA_CHECK_EQUAL( shadowStorage.size(), 0 ); - SphereID bd = static_cast<SphereID> (*(storage[0].find( sid ))); + SphereID bd = static_cast<SphereID> (storage[0].find( sid ).getBodyID()); WALBERLA_CHECK_NOT_NULLPTR(bd); checkVitalParameters(bd, ref); bd->setPosition( newPos ); @@ -100,7 +100,7 @@ void checkSphere(StructuredBlockForest& forest, BlockDataID storageID, walberla: { WALBERLA_CHECK_EQUAL( storage[0].size(), 0 ); WALBERLA_CHECK_EQUAL( shadowStorage.size(), 1, "ref_sphere: " << ref << "\n" << block.getAABB() ); - SphereID bd = static_cast<SphereID> (*(shadowStorage.find( sid ))); + SphereID bd = static_cast<SphereID> (shadowStorage.find( sid ).getBodyID()); WALBERLA_CHECK_NOT_NULLPTR(bd); auto backupPos =ref->getPosition(); auto correctedPos = ref->getPosition(); @@ -161,9 +161,9 @@ int main( int argc, char ** argv ) walberla::id_t sid = 123; Vec3 gpos = Vec3(3.5, 3.5, 3.5); const real_t r = real_c(1.6); - SphereID refSphere = new Sphere(1, 0, gpos, Vec3(0,0,0), Quat(), r, iron, false, true, false); - refSphere->setLinearVel(4, 5, 6); - refSphere->setAngularVel( 1, 2, 3); + Sphere refSphere(1, 0, gpos, Vec3(0,0,0), Quat(), r, iron, false, true, false); + refSphere.setLinearVel(4, 5, 6); + refSphere.setAngularVel( 1, 2, 3); SphereID sphere = createSphere( *globalStorage, forest->getBlockStorage(), storageID, 0, gpos, r); @@ -203,10 +203,10 @@ int main( int argc, char ** argv ) for (int i = 0; i < 21; ++i) { syncShadowOwners<BodyTuple>(forest->getBlockForest(), storageID); - Vec3 pos = refSphere->getPosition() + delta; + Vec3 pos = refSphere.getPosition() + delta; if (!forest->getDomain().contains( pos, real_c(0.5) )) forest->mapToPeriodicDomain(pos); - checkSphere(*forest, storageID, sid, refSphere, pos); + checkSphere(*forest, storageID, sid, &refSphere, pos); } } WALBERLA_LOG_PROGRESS("TEST WITHOUT DX ... finished"); @@ -225,10 +225,10 @@ int main( int argc, char ** argv ) for (int i = 0; i < 21; ++i) { syncShadowOwners<BodyTuple>(forest->getBlockForest(), storageID, NULL, dx); - Vec3 pos = refSphere->getPosition() + delta; + Vec3 pos = refSphere.getPosition() + delta; if (!forest->getDomain().contains( pos, real_c(0.5) )) forest->mapToPeriodicDomain(pos); - checkSphere(*forest, storageID, sid, refSphere, pos, dx); + checkSphere(*forest, storageID, sid, &refSphere, pos, dx); } } syncShadowOwners<BodyTuple>(forest->getBlockForest(), storageID, NULL, dx); diff --git a/tests/pe/Union.cpp b/tests/pe/Union.cpp index 6cd0aec53e1e26b978b0085a67a04ae74b15fc0e..1a814c28a1a6a789eadf5a34d1c352f23b0baf8b 100644 --- a/tests/pe/Union.cpp +++ b/tests/pe/Union.cpp @@ -25,6 +25,7 @@ #include "pe/basic.h" #include "pe/rigidbody/Union.h" +#include "pe/rigidbody/UnionFactory.h" #include "pe/ccd/SimpleCCDDataHandling.h" #include "pe/synchronization/SyncNextNeighbors.h" #include "pe/vtk/BodyVtkOutput.h" @@ -75,12 +76,9 @@ void SnowManFallingOnPlane() createPlane( *globalBodyStorage, 0, Vec3(0,0,1), Vec3(0,0,0) ); - MaterialID iron = Material::find("iron"); - UnionType* un = createUnion< boost::tuple<Sphere> >( *globalBodyStorage, forest->getBlockStorage(), storageID, 0, Vec3(5,5,5) ); - SphereID sp1 = new Sphere( 10, 0, Vec3(5,5,1), Vec3(0,0,0), Quat(), real_t(1) , iron, false, true, false ); - SphereID sp2 = new Sphere( 11, 0, Vec3(real_t(6.7),5,real_t(1.2)), Vec3(0,0,0), Quat(), real_t(1.1), iron, false, true, false ); - un->add(sp1); - un->add(sp2); + UnionType* un = createUnion< boost::tuple<Sphere> >( *globalBodyStorage, forest->getBlockStorage(), storageID, 0, Vec3(5,5,5) ); + auto sp1 = createSphere(un, 10, Vec3(5,5,1), real_t(1)); + auto sp2 = createSphere(un, 11, Vec3(real_t(6.7),5,real_t(1.2)), real_t(1.1)); auto distance = (sp1->getPosition() - sp2->getPosition()).length(); @@ -106,14 +104,15 @@ void ImpulsCarryover() { MaterialID iron = Material::find("iron"); - UnionType* un = new Union< boost::tuple<Sphere> >(12, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), false, true, false); - SphereID sp1 = new Sphere( 10, 0, Vec3( 1,0,0), Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false ); - SphereID sp2 = new Sphere( 11, 0, Vec3(-1,0,0), Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false ); + auto un = std::make_unique<UnionType>(12, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), false, true, false); + auto sp1 = std::make_unique<Sphere>( 10, 0, Vec3( 1,0,0), Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false ); + auto sp2 = std::make_unique<Sphere>( 11, 0, Vec3(-1,0,0), Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false ); + sp1->setLinearVel(Vec3(0,real_c(+1),0)); sp2->setLinearVel(Vec3(0,real_c(-1),0)); - un->add(sp1); - un->add(sp2); + un->add( std::move(sp1) ); + un->add( std::move(sp2) ); WALBERLA_CHECK_FLOAT_EQUAL( un->getPosition(), Vec3(0,0,0) ); WALBERLA_CHECK_FLOAT_EQUAL( un->getLinearVel(), Vec3(0,0,0) ); diff --git a/tests/pe_coupling/discrete_particle_methods/HinderedSettlingDynamicsDPM.cpp b/tests/pe_coupling/discrete_particle_methods/HinderedSettlingDynamicsDPM.cpp index d9fd267079e1b78d322a80ff1e7afdd1aabc3755..ca71c9f03e5f806abae1842c53190c4847dae8fd 100644 --- a/tests/pe_coupling/discrete_particle_methods/HinderedSettlingDynamicsDPM.cpp +++ b/tests/pe_coupling/discrete_particle_methods/HinderedSettlingDynamicsDPM.cpp @@ -44,6 +44,7 @@ #include "vtk/VTKOutput.h" +#include <functional> #include <vector> #include <iomanip> #include <iostream> @@ -851,7 +852,7 @@ int main( int argc, char **argv ) // connect to pe const real_t overlap = real_t( 1.5 ) * dx; - auto syncCall = boost::bind( pe::syncNextNeighbors<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); + auto syncCall = std::bind( pe::syncNextNeighbors<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); shared_ptr<CollisionPropertiesEvaluator> collisionPropertiesEvaluator = walberla::make_shared<CollisionPropertiesEvaluator>( *cr ); // create the spheres @@ -1147,7 +1148,7 @@ int main( int argc, char **argv ) velocityFieldID, svfFieldID, pressureGradientFieldID, dragCorrelationFunction, viscosity); - dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if (dist == Distribution::DKernel) { typedef pe_coupling::discrete_particle_methods::InteractionForceEvaluator<FlagField_T, field::NearestNeighborFieldInterpolator, field::KernelDistributor> IFE_T; shared_ptr<IFE_T> forceEvaluatorPtr = make_shared<IFE_T>(blocks, dragForceFieldID, bodyStorageID, @@ -1155,7 +1156,7 @@ int main( int argc, char **argv ) velocityFieldID, svfFieldID, pressureGradientFieldID, dragCorrelationFunction, viscosity); - dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } else if (interpol == Interpolation::IKernel) { if (dist == Distribution::DNearestNeighbor) { @@ -1165,7 +1166,7 @@ int main( int argc, char **argv ) velocityFieldID, svfFieldID, pressureGradientFieldID, dragCorrelationFunction, viscosity); - dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if (dist == Distribution::DKernel) { typedef pe_coupling::discrete_particle_methods::InteractionForceEvaluator<FlagField_T, field::KernelFieldInterpolator, field::KernelDistributor> IFE_T; shared_ptr<IFE_T> forceEvaluatorPtr = make_shared<IFE_T>(blocks, dragForceFieldID, bodyStorageID, @@ -1173,7 +1174,7 @@ int main( int argc, char **argv ) velocityFieldID, svfFieldID, pressureGradientFieldID, dragCorrelationFunction, viscosity); - dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } else if (interpol == Interpolation::ITrilinear) { if (dist == Distribution::DNearestNeighbor) { @@ -1183,7 +1184,7 @@ int main( int argc, char **argv ) velocityFieldID, svfFieldID, pressureGradientFieldID, dragCorrelationFunction, viscosity); - dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if (dist == Distribution::DKernel) { typedef pe_coupling::discrete_particle_methods::InteractionForceEvaluator<FlagField_T, field::TrilinearFieldInterpolator, field::KernelDistributor> IFE_T; shared_ptr<IFE_T> forceEvaluatorPtr = make_shared<IFE_T>(blocks, dragForceFieldID, bodyStorageID, @@ -1191,7 +1192,7 @@ int main( int argc, char **argv ) velocityFieldID, svfFieldID, pressureGradientFieldID, dragCorrelationFunction, viscosity); - dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } } @@ -1211,7 +1212,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, velocityFieldID, velocityCurlFieldID, liftCorrelationFunction, viscosity ); - liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if( dist == Distribution::DKernel ) { @@ -1219,7 +1220,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, velocityFieldID, velocityCurlFieldID, liftCorrelationFunction, viscosity ); - liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } else if( interpol == Interpolation::IKernel ) @@ -1230,7 +1231,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, velocityFieldID, velocityCurlFieldID, liftCorrelationFunction, viscosity ); - liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if( dist == Distribution::DKernel ) { @@ -1238,7 +1239,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, velocityFieldID, velocityCurlFieldID, liftCorrelationFunction, viscosity ); - liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } else if( interpol == Interpolation::ITrilinear ) @@ -1249,7 +1250,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, velocityFieldID, velocityCurlFieldID, liftCorrelationFunction, viscosity ); - liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if( dist == Distribution::DKernel ) { @@ -1257,7 +1258,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, velocityFieldID, velocityCurlFieldID, liftCorrelationFunction, viscosity ); - liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } @@ -1271,7 +1272,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, timeDerivativeVelocityFieldID, addedMassCorrelationFunction, bodyVelocityTimeDerivativeEvaluator ); - addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if( dist == Distribution::DKernel ) { @@ -1279,7 +1280,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, timeDerivativeVelocityFieldID, addedMassCorrelationFunction, bodyVelocityTimeDerivativeEvaluator ); - addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } else if( interpol == Interpolation::IKernel ) @@ -1290,7 +1291,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, timeDerivativeVelocityFieldID, addedMassCorrelationFunction, bodyVelocityTimeDerivativeEvaluator ); - addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if( dist == Distribution::DKernel ) { @@ -1298,7 +1299,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, timeDerivativeVelocityFieldID, addedMassCorrelationFunction, bodyVelocityTimeDerivativeEvaluator ); - addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } else if( interpol == Interpolation::ITrilinear ) @@ -1309,7 +1310,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, timeDerivativeVelocityFieldID, addedMassCorrelationFunction, bodyVelocityTimeDerivativeEvaluator ); - addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if( dist == Distribution::DKernel ) { @@ -1317,7 +1318,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, timeDerivativeVelocityFieldID, addedMassCorrelationFunction, bodyVelocityTimeDerivativeEvaluator ); - addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } @@ -1329,13 +1330,13 @@ int main( int argc, char **argv ) { typedef pe_coupling::LubricationCorrection LE_T; shared_ptr<LE_T> lubEval = make_shared<LE_T>( blocks, globalBodyStorage, bodyStorageID, viscosity, lubricationCutOffDistance ); - lubricationEvaluationFunction = boost::bind(&LE_T::operator(), lubEval); + lubricationEvaluationFunction = std::bind(&LE_T::operator(), lubEval); } else { typedef pe_coupling::discrete_particle_methods::LubricationForceEvaluator LE_T; shared_ptr<LE_T> lubEval = make_shared<LE_T>( blocks, globalBodyStorage, bodyStorageID, viscosity, lubricationCutOffDistance ); - lubricationEvaluationFunction = boost::bind(&LE_T::operator(), lubEval); + lubricationEvaluationFunction = std::bind(&LE_T::operator(), lubEval); } } else { lubricationEvaluationFunction = emptyFunction; @@ -1343,7 +1344,7 @@ int main( int argc, char **argv ) // function to evaluate the mean fluid velocity - std::function<Vector3<real_t> ()> evaluateMeanFluidVelocity = boost::bind(getGNSMeanFluidVelocity, blocks, pdfFieldID, svfFieldID, domainVolume); + std::function<Vector3<real_t> ()> evaluateMeanFluidVelocity = std::bind(getGNSMeanFluidVelocity, blocks, pdfFieldID, svfFieldID, domainVolume); ////////////////////////////// diff --git a/tests/pe_coupling/discrete_particle_methods/SphereWallCollisionBehaviorDPM.cpp b/tests/pe_coupling/discrete_particle_methods/SphereWallCollisionBehaviorDPM.cpp index 5ec32af40e6dc4dae10443bdb2f31f1bd01c791f..052676d3f0adcc1d0cf63abbd1888f9e1222ce9d 100644 --- a/tests/pe_coupling/discrete_particle_methods/SphereWallCollisionBehaviorDPM.cpp +++ b/tests/pe_coupling/discrete_particle_methods/SphereWallCollisionBehaviorDPM.cpp @@ -44,6 +44,7 @@ #include "vtk/VTKOutput.h" #include <vector> +#include <functional> #include <iomanip> #include <iostream> #include <random> @@ -698,7 +699,7 @@ int main( int argc, char **argv ) // connect to pe const real_t overlap = real_t( 1.5 ) * dx; - auto syncCall = boost::bind( pe::syncNextNeighbors<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); + auto syncCall = std::bind( pe::syncNextNeighbors<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); // create the sphere const real_t restitutionCoeff = real_t(0.97); @@ -943,7 +944,7 @@ int main( int argc, char **argv ) velocityFieldID, svfFieldID, pressureGradientFieldID, dragCorrelationFunction, viscosity); - dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if (dist == Distribution::DKernel) { typedef pe_coupling::discrete_particle_methods::InteractionForceEvaluator<FlagField_T, field::NearestNeighborFieldInterpolator, field::KernelDistributor> IFE_T; shared_ptr<IFE_T> forceEvaluatorPtr = make_shared<IFE_T>(blocks, dragForceFieldID, bodyStorageID, @@ -951,7 +952,7 @@ int main( int argc, char **argv ) velocityFieldID, svfFieldID, pressureGradientFieldID, dragCorrelationFunction, viscosity); - dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } else if (interpol == Interpolation::IKernel) { if (dist == Distribution::DNearestNeighbor) { @@ -961,7 +962,7 @@ int main( int argc, char **argv ) velocityFieldID, svfFieldID, pressureGradientFieldID, dragCorrelationFunction, viscosity); - dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if (dist == Distribution::DKernel) { typedef pe_coupling::discrete_particle_methods::InteractionForceEvaluator<FlagField_T, field::KernelFieldInterpolator, field::KernelDistributor> IFE_T; shared_ptr<IFE_T> forceEvaluatorPtr = make_shared<IFE_T>(blocks, dragForceFieldID, bodyStorageID, @@ -969,7 +970,7 @@ int main( int argc, char **argv ) velocityFieldID, svfFieldID, pressureGradientFieldID, dragCorrelationFunction, viscosity); - dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } else if (interpol == Interpolation::ITrilinear) { if (dist == Distribution::DNearestNeighbor) { @@ -979,7 +980,7 @@ int main( int argc, char **argv ) velocityFieldID, svfFieldID, pressureGradientFieldID, dragCorrelationFunction, viscosity); - dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if (dist == Distribution::DKernel) { typedef pe_coupling::discrete_particle_methods::InteractionForceEvaluator<FlagField_T, field::TrilinearFieldInterpolator, field::KernelDistributor> IFE_T; shared_ptr<IFE_T> forceEvaluatorPtr = make_shared<IFE_T>(blocks, dragForceFieldID, bodyStorageID, @@ -987,7 +988,7 @@ int main( int argc, char **argv ) velocityFieldID, svfFieldID, pressureGradientFieldID, dragCorrelationFunction, viscosity); - dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } } @@ -1007,7 +1008,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, velocityFieldID, velocityCurlFieldID, liftCorrelationFunction, viscosity ); - liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if( dist == Distribution::DKernel ) { @@ -1015,7 +1016,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, velocityFieldID, velocityCurlFieldID, liftCorrelationFunction, viscosity ); - liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } else if( interpol == Interpolation::IKernel ) @@ -1026,7 +1027,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, velocityFieldID, velocityCurlFieldID, liftCorrelationFunction, viscosity ); - liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if( dist == Distribution::DKernel ) { @@ -1034,7 +1035,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, velocityFieldID, velocityCurlFieldID, liftCorrelationFunction, viscosity ); - liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } else if( interpol == Interpolation::ITrilinear ) @@ -1045,7 +1046,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, velocityFieldID, velocityCurlFieldID, liftCorrelationFunction, viscosity ); - liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if( dist == Distribution::DKernel ) { @@ -1053,7 +1054,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, velocityFieldID, velocityCurlFieldID, liftCorrelationFunction, viscosity ); - liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } @@ -1068,7 +1069,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, timeDerivativeVelocityFieldID, addedMassCorrelationFunction, bodyVelocityTimeDerivativeEvaluator ); - addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if( dist == Distribution::DKernel ) { @@ -1076,7 +1077,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, timeDerivativeVelocityFieldID, addedMassCorrelationFunction, bodyVelocityTimeDerivativeEvaluator ); - addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } else if( interpol == Interpolation::IKernel ) @@ -1087,7 +1088,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, timeDerivativeVelocityFieldID, addedMassCorrelationFunction, bodyVelocityTimeDerivativeEvaluator ); - addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if( dist == Distribution::DKernel ) { @@ -1095,7 +1096,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, timeDerivativeVelocityFieldID, addedMassCorrelationFunction, bodyVelocityTimeDerivativeEvaluator ); - addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } else if( interpol == Interpolation::ITrilinear ) @@ -1106,7 +1107,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, timeDerivativeVelocityFieldID, addedMassCorrelationFunction, bodyVelocityTimeDerivativeEvaluator ); - addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } else if( dist == Distribution::DKernel ) { @@ -1114,7 +1115,7 @@ int main( int argc, char **argv ) shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag, timeDerivativeVelocityFieldID, addedMassCorrelationFunction, bodyVelocityTimeDerivativeEvaluator ); - addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr); + addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr); } } @@ -1126,13 +1127,13 @@ int main( int argc, char **argv ) { typedef pe_coupling::LubricationCorrection LE_T; shared_ptr<LE_T> lubEval = make_shared<LE_T>( blocks, globalBodyStorage, bodyStorageID, viscosity, lubricationCutOffDistance ); - lubricationEvaluationFunction = boost::bind(&LE_T::operator(), lubEval); + lubricationEvaluationFunction = std::bind(&LE_T::operator(), lubEval); } else { typedef pe_coupling::discrete_particle_methods::LubricationForceEvaluator LE_T; shared_ptr<LE_T> lubEval = make_shared<LE_T>( blocks, globalBodyStorage, bodyStorageID, viscosity, lubricationCutOffDistance ); - lubricationEvaluationFunction = boost::bind(&LE_T::operator(), lubEval); + lubricationEvaluationFunction = std::bind(&LE_T::operator(), lubEval); } } else { lubricationEvaluationFunction = emptyFunction; diff --git a/tests/pe_coupling/momentum_exchange_method/BodyAtBlockBoarderCheck.cpp b/tests/pe_coupling/momentum_exchange_method/BodyAtBlockBoarderCheck.cpp index 4133741c77ebb5f7bf427b77ad096f0ab0c2ea33..bbf5224bf01124e9f8a0864e5e53130c21145105 100644 --- a/tests/pe_coupling/momentum_exchange_method/BodyAtBlockBoarderCheck.cpp +++ b/tests/pe_coupling/momentum_exchange_method/BodyAtBlockBoarderCheck.cpp @@ -64,6 +64,7 @@ #include <vector> #include <iomanip> #include <iostream> +#include <functional> namespace body_at_block_boarder_check { @@ -132,7 +133,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( AABB domainAABB uint_c(domainAABB.zMax()) / blockSizeInCells[2] ); AABB refinementBox( domainAABB.xMin(), domainAABB.yMin(), domainAABB.zMin(), domainAABB.xMax() * real_c(0.5), domainAABB.yMax(), domainAABB.zMax() ); - sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, numberOfLevels, refinementBox ) ); + sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, numberOfLevels, refinementBox ) ); sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment ); sforest.init( domainAABB, numberOfCoarseBlocksPerDirection[0], numberOfCoarseBlocksPerDirection[1], numberOfCoarseBlocksPerDirection[2], true, true, true ); @@ -281,7 +282,7 @@ int main( int argc, char **argv ) // connect to pe const real_t overlap = real_c( 1.5 ) * dx; - std::function<void(void)> syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); + std::function<void(void)> syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); auto sphereMaterialID = pe::createMaterial( "sphereMat", real_c(1) , real_c(0.3), real_c(0.2), real_c(0.2), real_c(0.24), real_c(200), real_c(200), real_c(0), real_c(0) ); // create two spheres: one which overlaps with a block boundary and one inside the block diff --git a/tests/pe_coupling/momentum_exchange_method/DragForceSphereMEMRefinement.cpp b/tests/pe_coupling/momentum_exchange_method/DragForceSphereMEMRefinement.cpp index a084604c75313af11681480e13bc5ba1d11fcaba..33371ade972cb4f1315a3edb6838e8cad5a7c011 100644 --- a/tests/pe_coupling/momentum_exchange_method/DragForceSphereMEMRefinement.cpp +++ b/tests/pe_coupling/momentum_exchange_method/DragForceSphereMEMRefinement.cpp @@ -67,6 +67,7 @@ #include "field/vtk/all.h" #include "lbm/vtk/all.h" +#include <functional> #include <vector> #include <iomanip> #include <iostream> @@ -165,7 +166,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( const Setup & s // initialize SetupBlockForest = determine domain decomposition SetupBlockForest sforest; - sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, setup.levels, setup.radius * real_c(2), setup.length ) ); + sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, setup.levels, setup.radius * real_c(2), setup.length ) ); sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment ); sforest.init( AABB( real_c(0), real_c(0), real_c(0), setup.length, setup.length, setup.length ), diff --git a/tests/pe_coupling/momentum_exchange_method/GlobalBodyAsBoundaryMEMStaticRefinement.cpp b/tests/pe_coupling/momentum_exchange_method/GlobalBodyAsBoundaryMEMStaticRefinement.cpp index 27626a2e5d93b95e14850edf93265aebfd06bca5..393df5213fede9b51d2596568193800f5a474a8f 100644 --- a/tests/pe_coupling/momentum_exchange_method/GlobalBodyAsBoundaryMEMStaticRefinement.cpp +++ b/tests/pe_coupling/momentum_exchange_method/GlobalBodyAsBoundaryMEMStaticRefinement.cpp @@ -60,6 +60,8 @@ #include "field/vtk/all.h" #include "lbm/vtk/all.h" +#include <functional> + namespace global_body_as_boundary_mem_static_refinement { @@ -163,7 +165,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( const AABB & do WALBERLA_LOG_INFO_ON_ROOT(" - refinement box: " << refinementBox); - sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, numberOfLevels, refinementBox ) ); + sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, numberOfLevels, refinementBox ) ); sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment ); sforest.init( domainAABB, numberOfCoarseBlocksPerDirection[0], numberOfCoarseBlocksPerDirection[1], numberOfCoarseBlocksPerDirection[2], false, false, false ); diff --git a/tests/pe_coupling/momentum_exchange_method/LubricationCorrectionMEM.cpp b/tests/pe_coupling/momentum_exchange_method/LubricationCorrectionMEM.cpp index d0d021395ac9fdebda1baca45cb0bc78b13449ae..26a984714fff6dac3d8c0452df6e79331aacffc6 100644 --- a/tests/pe_coupling/momentum_exchange_method/LubricationCorrectionMEM.cpp +++ b/tests/pe_coupling/momentum_exchange_method/LubricationCorrectionMEM.cpp @@ -57,6 +57,8 @@ #include "pe_coupling/momentum_exchange_method/all.h" #include "pe_coupling/utility/all.h" +#include <functional> + namespace lubrication_correction_mem { @@ -163,14 +165,14 @@ private: { for( auto curSphereIt = pe::BodyIterator::begin<pe::Sphere>( *blockIt, bodyStorageID_); curSphereIt != pe::BodyIterator::end<pe::Sphere>(); ++curSphereIt ) { - pe::SphereID sphereI = ( *curSphereIt ); + pe::SphereID sphereI = ( curSphereIt.getBodyID() ); if ( sphereI->getID() == id1_ ) { for( auto blockIt2 = blocks_->begin(); blockIt2 != blocks_->end(); ++blockIt2 ) { for( auto oSphereIt = pe::BodyIterator::begin<pe::Sphere>( *blockIt2, bodyStorageID_); oSphereIt != pe::BodyIterator::end<pe::Sphere>(); ++oSphereIt ) { - pe::SphereID sphereJ = ( *oSphereIt ); + pe::SphereID sphereJ = ( oSphereIt.getBodyID() ); if ( sphereJ->getID() == id2_ ) { gap = pe::getSurfaceDistance( sphereI, sphereJ ); @@ -283,14 +285,14 @@ private: { for( auto curSphereIt = pe::BodyIterator::begin<pe::Sphere>( *blockIt, bodyStorageID_); curSphereIt != pe::BodyIterator::end<pe::Sphere>(); ++curSphereIt ) { - pe::SphereID sphereI = ( *curSphereIt ); + pe::SphereID sphereI = ( curSphereIt.getBodyID() ); if ( sphereI->getID() == id1_ ) { for( auto globalBodyIt = globalBodyStorage_->begin(); globalBodyIt != globalBodyStorage_->end(); ++globalBodyIt) { if( globalBodyIt->getID() == id2_ ) { - pe::PlaneID planeJ = static_cast<pe::PlaneID>( *globalBodyIt ); + pe::PlaneID planeJ = static_cast<pe::PlaneID>( globalBodyIt.getBodyID() ); gap = pe::getSurfaceDistance(sphereI, planeJ); break; } @@ -789,7 +791,7 @@ int main( int argc, char **argv ) // set up synchronization procedure const real_t overlap = real_c( 1.5 ) * dx; - std::function<void(void)> syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); + std::function<void(void)> syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); // create the material const auto myMat = pe::createMaterial( "myMat", real_c(1.4), real_t(0), real_t(1), real_t(1), real_t(0), real_t(1), real_t(1), real_t(0), real_t(0) ); diff --git a/tests/pe_coupling/momentum_exchange_method/PeriodicParticleChannelMEM.cpp b/tests/pe_coupling/momentum_exchange_method/PeriodicParticleChannelMEM.cpp index ef64aa7a87b345e84e5bd1390f18b008667064a7..bbf831d830ea84b7e37aa22d1668787256275546 100644 --- a/tests/pe_coupling/momentum_exchange_method/PeriodicParticleChannelMEM.cpp +++ b/tests/pe_coupling/momentum_exchange_method/PeriodicParticleChannelMEM.cpp @@ -65,6 +65,7 @@ #include "vtk/all.h" +#include <functional> #include <vector> namespace periodic_particle_channel_mem @@ -413,7 +414,7 @@ int main( int argc, char **argv ) // set up synchronization procedure const real_t overlap = real_c( 1.5 ) * dx; - std::function<void(void)> syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); + std::function<void(void)> syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); // create pe bodies const auto material = pe::createMaterial( "granular", real_c(1.2), real_c(0.25), real_c(0.4), real_c(0.4), real_c(0.35), real_c(1.39e11), real_c(5.18e7), real_c(1.07e2), real_c(1.07e2) ); diff --git a/tests/pe_coupling/momentum_exchange_method/SegreSilberbergMEM.cpp b/tests/pe_coupling/momentum_exchange_method/SegreSilberbergMEM.cpp index 6ccc9f5c7d5156ba058991860ccb271ecbcbfe91..c05c2636c7caa4c300f94c5dadfd0f2177bc947e 100644 --- a/tests/pe_coupling/momentum_exchange_method/SegreSilberbergMEM.cpp +++ b/tests/pe_coupling/momentum_exchange_method/SegreSilberbergMEM.cpp @@ -65,6 +65,8 @@ #include "field/vtk/all.h" #include "lbm/vtk/all.h" +#include <functional> + namespace segre_silberberg_mem { @@ -549,10 +551,10 @@ int main( int argc, char **argv ) std::function<void(void)> syncCall; if (!syncShadowOwners) { - syncCall = boost::bind( pe::syncNextNeighbors<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); + syncCall = std::bind( pe::syncNextNeighbors<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); } else { - syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); + syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); } // create pe bodies @@ -670,9 +672,9 @@ int main( int argc, char **argv ) } shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer1 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID); - std::function<void(void)> storeForceTorqueInCont1 = boost::bind(&pe_coupling::BodiesForceTorqueContainer::store, bodiesFTContainer1); + std::function<void(void)> storeForceTorqueInCont1 = std::bind(&pe_coupling::BodiesForceTorqueContainer::store, bodiesFTContainer1); shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer2 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID); - std::function<void(void)> setForceTorqueOnBodiesFromCont2 = boost::bind(&pe_coupling::BodiesForceTorqueContainer::setOnBodies, bodiesFTContainer2); + std::function<void(void)> setForceTorqueOnBodiesFromCont2 = std::bind(&pe_coupling::BodiesForceTorqueContainer::setOnBodies, bodiesFTContainer2); bodiesFTContainer2->store(); diff --git a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEM.cpp b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEM.cpp index 6674cde01316e65119f1738ef249945b0614fca2..ed9c8da8cfdb28470feee2022e07ad3f299873af 100644 --- a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEM.cpp +++ b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEM.cpp @@ -63,6 +63,8 @@ #include "field/vtk/all.h" #include "lbm/vtk/all.h" +#include <functional> + namespace settling_sphere_mem { @@ -457,7 +459,7 @@ int main( int argc, char **argv ) // set up synchronization procedure const real_t overlap = real_t( 1.5 ) * dx; - std::function<void(void)> syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); + std::function<void(void)> syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); // create pe bodies @@ -530,11 +532,11 @@ int main( int argc, char **argv ) ( blocks, boundaryHandlingID, bodyStorageID, globalBodyStorage, bodyFieldID, reconstructor, FormerMO_Flag, Fluid_Flag ), "PDF Restore" ); shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer1 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID); - std::function<void(void)> storeForceTorqueInCont1 = boost::bind(&pe_coupling::BodiesForceTorqueContainer::store, bodiesFTContainer1); + std::function<void(void)> storeForceTorqueInCont1 = std::bind(&pe_coupling::BodiesForceTorqueContainer::store, bodiesFTContainer1); shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer2 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID); - std::function<void(void)> setForceTorqueOnBodiesFromCont2 = boost::bind(&pe_coupling::BodiesForceTorqueContainer::setOnBodies, bodiesFTContainer2); + std::function<void(void)> setForceTorqueOnBodiesFromCont2 = std::bind(&pe_coupling::BodiesForceTorqueContainer::setOnBodies, bodiesFTContainer2); shared_ptr<pe_coupling::ForceTorqueOnBodiesScaler> forceScaler = make_shared<pe_coupling::ForceTorqueOnBodiesScaler>(blocks, bodyStorageID, real_t(1)); - std::function<void(void)> setForceScalingFactorToHalf = boost::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(0.5)); + std::function<void(void)> setForceScalingFactorToHalf = std::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(0.5)); if( averageForceTorqueOverTwoTimSteps ) { bodiesFTContainer2->store(); diff --git a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMDynamicRefinement.cpp b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMDynamicRefinement.cpp index 44b17eb70ee97b509d096e0b09133d97bc40efc8..6ebde5403e925066e172980f9286ca4f4455311d 100644 --- a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMDynamicRefinement.cpp +++ b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMDynamicRefinement.cpp @@ -65,6 +65,8 @@ #include "field/vtk/all.h" #include "lbm/vtk/all.h" +#include <functional> + namespace settling_sphere_mem_dynamic_refinement { @@ -251,7 +253,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( const AABB & do WALBERLA_LOG_INFO_ON_ROOT(" - refinement box: " << refinementBox); - sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, numberOfLevels, refinementBox ) ); + sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, numberOfLevels, refinementBox ) ); sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment ); sforest.init( domainAABB, numberOfCoarseBlocksPerDirection[0], numberOfCoarseBlocksPerDirection[1], numberOfCoarseBlocksPerDirection[2], false, false, false ); @@ -677,7 +679,7 @@ int main( int argc, char **argv ) // set up synchronization procedure const real_t overlap = real_t( 1.5 ) * dx; - std::function<void(void)> syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); + std::function<void(void)> syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); // create pe bodies @@ -728,12 +730,12 @@ int main( int argc, char **argv ) // force averaging functionality shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer1 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID); - std::function<void(void)> storeForceTorqueInCont1 = boost::bind(&pe_coupling::BodiesForceTorqueContainer::store, bodiesFTContainer1); + std::function<void(void)> storeForceTorqueInCont1 = std::bind(&pe_coupling::BodiesForceTorqueContainer::store, bodiesFTContainer1); shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer2 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID); - std::function<void(void)> setForceTorqueOnBodiesFromCont2 = boost::bind(&pe_coupling::BodiesForceTorqueContainer::setOnBodies, bodiesFTContainer2); + std::function<void(void)> setForceTorqueOnBodiesFromCont2 = std::bind(&pe_coupling::BodiesForceTorqueContainer::setOnBodies, bodiesFTContainer2); shared_ptr<pe_coupling::ForceTorqueOnBodiesScaler> forceScaler = make_shared<pe_coupling::ForceTorqueOnBodiesScaler>(blocks, bodyStorageID, real_t(0.5)); - std::function<void(void)> setForceScalingFactorToOne = boost::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(1)); - std::function<void(void)> setForceScalingFactorToHalf = boost::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(0.5)); + std::function<void(void)> setForceScalingFactorToOne = std::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(1)); + std::function<void(void)> setForceScalingFactorToHalf = std::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(0.5)); if( averageForceTorqueOverTwoTimSteps ) { bodiesFTContainer2->store(); @@ -869,9 +871,18 @@ int main( int argc, char **argv ) { auto & forest = blocks->getBlockForest(); pe::createWithNeighborhood(forest, bodyStorageID, *peInfoCollection); - pe::clearSynchronization( blockforest, bodyStorageID); + uint_t stampBefore = blocks->getBlockForest().getModificationStamp(); blocks->refresh(); + uint_t stampAfter = blocks->getBlockForest().getModificationStamp(); + + if(stampBefore == stampAfter) + { + // nothing has changed + continue; + } + + pe::clearSynchronization( blockforest, bodyStorageID); for( uint_t syncStep = 0; syncStep < uint_c(diameter / real_c(minBlockSizeInCells)) + 1; ++syncStep) syncCall(); diff --git a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMStaticRefinement.cpp b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMStaticRefinement.cpp index 391ab7b8947bd32cc518760d4fc726c96ceae4c6..b8cbd96b2793d02b8c52bae95f38038e7263992d 100644 --- a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMStaticRefinement.cpp +++ b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMStaticRefinement.cpp @@ -63,6 +63,8 @@ #include "field/vtk/all.h" #include "lbm/vtk/all.h" +#include <functional> + namespace settling_sphere_mem_static_refinement { @@ -170,7 +172,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( const AABB & do WALBERLA_LOG_INFO_ON_ROOT(" - refinement box: " << refinementBox); - sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, numberOfLevels, refinementBox ) ); + sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, numberOfLevels, refinementBox ) ); sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment ); sforest.init( domainAABB, numberOfCoarseBlocksPerDirection[0], numberOfCoarseBlocksPerDirection[1], numberOfCoarseBlocksPerDirection[2], false, false, false ); @@ -544,7 +546,7 @@ int main( int argc, char **argv ) // set up synchronization procedure const real_t overlap = real_t( 1.5 ) * dx; - std::function<void(void)> syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); + std::function<void(void)> syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); // create pe bodies @@ -595,11 +597,11 @@ int main( int argc, char **argv ) // force averaging functionality shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer1 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID); - std::function<void(void)> storeForceTorqueInCont1 = boost::bind(&pe_coupling::BodiesForceTorqueContainer::store, bodiesFTContainer1); + std::function<void(void)> storeForceTorqueInCont1 = std::bind(&pe_coupling::BodiesForceTorqueContainer::store, bodiesFTContainer1); shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer2 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID); - std::function<void(void)> setForceTorqueOnBodiesFromCont2 = boost::bind(&pe_coupling::BodiesForceTorqueContainer::setOnBodies, bodiesFTContainer2); + std::function<void(void)> setForceTorqueOnBodiesFromCont2 = std::bind(&pe_coupling::BodiesForceTorqueContainer::setOnBodies, bodiesFTContainer2); shared_ptr<pe_coupling::ForceTorqueOnBodiesScaler> forceScaler = make_shared<pe_coupling::ForceTorqueOnBodiesScaler>(blocks, bodyStorageID, real_t(1)); - std::function<void(void)> setForceScalingFactorToHalf = boost::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(0.5)); + std::function<void(void)> setForceScalingFactorToHalf = std::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(0.5)); if( averageForceTorqueOverTwoTimSteps ) { bodiesFTContainer2->store(); diff --git a/tests/pe_coupling/momentum_exchange_method/SquirmerTest.cpp b/tests/pe_coupling/momentum_exchange_method/SquirmerTest.cpp index 82fd1093713a0421ace63341e6a65225b41f2534..08a7ad4d2b61ebaa7c6108255619423a10127763 100644 --- a/tests/pe_coupling/momentum_exchange_method/SquirmerTest.cpp +++ b/tests/pe_coupling/momentum_exchange_method/SquirmerTest.cpp @@ -66,6 +66,7 @@ #include "lbm/vtk/Velocity.h" #include "vtk/VTKOutput.h" +#include <functional> namespace squirmer { @@ -289,8 +290,8 @@ int main(int argc, char **argv) { return EXIT_FAILURE; } - std::function<void(void)> syncCall = boost::bind(pe::syncShadowOwners<BodyTypeTuple>, - boost::ref(blocks->getBlockForest()), bodyStorageID, + std::function<void(void)> syncCall = std::bind(pe::syncShadowOwners<BodyTypeTuple>, + std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree *>(NULL), overlap, false); const auto myMat = pe::createMaterial("myMat", real_c(1), real_t(0), real_t(1), real_t(1), real_t(0), real_t(1), diff --git a/tests/pe_coupling/momentum_exchange_method/TaylorCouetteFlowMEM.cpp b/tests/pe_coupling/momentum_exchange_method/TaylorCouetteFlowMEM.cpp index e6d43a5d0039a43d1aee67b9723f95d971e0b4de..54cf9698ead46a8afeb1a6b90a6cbca1ac4715b8 100644 --- a/tests/pe_coupling/momentum_exchange_method/TaylorCouetteFlowMEM.cpp +++ b/tests/pe_coupling/momentum_exchange_method/TaylorCouetteFlowMEM.cpp @@ -57,6 +57,8 @@ #include "vtk/all.h" +#include <functional> + namespace taylor_coette_flow_mem { @@ -303,7 +305,7 @@ int main( int argc, char **argv ) // set up synchronization procedure const real_t overlap = real_t( 1.5 ) * dx; - std::function<void(void)> syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); + std::function<void(void)> syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); // create pe bodies const auto material = pe::createMaterial( "granular", real_t(1.2), real_t(0.25), real_t(0.4), real_t(0.4), real_t(0.35), real_t(1.39e11), real_t(5.18e7), real_t(1.07e2), real_t(1.07e2) ); diff --git a/tests/pe_coupling/partially_saturated_cells_method/DragForceSpherePSMRefinement.cpp b/tests/pe_coupling/partially_saturated_cells_method/DragForceSpherePSMRefinement.cpp index f29f7d650c9e0bbd02ada920f48b4dd2cde1efee..d3b4fce22a25f4972df158c1331b29cc5d9e789e 100644 --- a/tests/pe_coupling/partially_saturated_cells_method/DragForceSpherePSMRefinement.cpp +++ b/tests/pe_coupling/partially_saturated_cells_method/DragForceSpherePSMRefinement.cpp @@ -67,6 +67,7 @@ #include "field/vtk/all.h" #include "lbm/vtk/all.h" +#include <functional> #include <vector> #include <iomanip> #include <iostream> @@ -185,7 +186,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( const Setup & s // initialize SetupBlockForest = determine domain decomposition SetupBlockForest sforest; - sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, setup.levels, setup.radius * real_c(2), real_c(setup.length) ) ); + sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, setup.levels, setup.radius * real_c(2), real_c(setup.length) ) ); sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment ); sforest.init( AABB( real_c(0), real_c(0), real_c(0), real_c(setup.length), real_c(setup.length), real_c(setup.length) ), diff --git a/tests/pe_coupling/partially_saturated_cells_method/SegreSilberbergPSM.cpp b/tests/pe_coupling/partially_saturated_cells_method/SegreSilberbergPSM.cpp index 7e0ad3250d28b0cb1f219bbae034dfdc77e817e2..f0153483fe0b11da945750d7f428fed8b22e02ac 100644 --- a/tests/pe_coupling/partially_saturated_cells_method/SegreSilberbergPSM.cpp +++ b/tests/pe_coupling/partially_saturated_cells_method/SegreSilberbergPSM.cpp @@ -64,6 +64,8 @@ #include "field/vtk/all.h" #include "lbm/vtk/all.h" +#include <functional> + namespace segre_silberberg_psm { @@ -502,7 +504,7 @@ int main( int argc, char **argv ) // set up synchronization procedure const real_t overlap = real_c( 1.5 ) * dx; - std::function<void(void)> syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); + std::function<void(void)> syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false ); // create pe bodies