diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e267b3fe71f579105a838ff259c4842ff45c04c..377f63451b882ec6c2a2b0c59838a6a88e990935 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -269,11 +269,14 @@ set(hpp_for_lib ${PROJECT_SOURCE_DIR}/cpp/particles/abstract_particles_input.hpp ${PROJECT_SOURCE_DIR}/cpp/particles/abstract_particles_output.hpp ${PROJECT_SOURCE_DIR}/cpp/particles/abstract_particles_system.hpp + ${PROJECT_SOURCE_DIR}/cpp/particles/abstract_particles_system_with_p2p.hpp ${PROJECT_SOURCE_DIR}/cpp/particles/alltoall_exchanger.hpp ${PROJECT_SOURCE_DIR}/cpp/particles/env_utils.hpp ${PROJECT_SOURCE_DIR}/cpp/particles/lock_free_bool_array.hpp ${PROJECT_SOURCE_DIR}/cpp/particles/p2p_computer_empty.hpp ${PROJECT_SOURCE_DIR}/cpp/particles/p2p_computer.hpp + ${PROJECT_SOURCE_DIR}/cpp/particles/p2p_ghost_collisions.hpp + ${PROJECT_SOURCE_DIR}/cpp/particles/p2p_cylinder_collisions.hpp ${PROJECT_SOURCE_DIR}/cpp/particles/p2p_distr_mpi.hpp ${PROJECT_SOURCE_DIR}/cpp/particles/p2p_tree.hpp ${PROJECT_SOURCE_DIR}/cpp/particles/particles_adams_bashforth.hpp diff --git a/cpp/particles/abstract_particles_system_with_p2p.hpp b/cpp/particles/abstract_particles_system_with_p2p.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3c31abf6f145ea1f130f64cae4eb281a1a83bdd2 --- /dev/null +++ b/cpp/particles/abstract_particles_system_with_p2p.hpp @@ -0,0 +1,13 @@ +#ifndef ABSTRACT_PARTICLES_SYSTEM_WITH_P2P_HPP +#define ABSTRACT_PARTICLES_SYSTEM_WITH_P2P_HPP + +#include "abstract_particles_system.hpp" + +template <class partsize_t, class real_number, class p2p_computer_class> +class abstract_particles_system_with_p2p : public abstract_particles_system<partsize_t,real_number> { +public: + virtual p2p_computer_class& getP2PComputer() = 0; + virtual const p2p_computer_class& getP2PComputer() const = 0; +}; + +#endif // ABSTRACT_PARTICLES_SYSTEM_WITH_P2P_HPP diff --git a/cpp/particles/p2p_computer.hpp b/cpp/particles/p2p_computer.hpp index 74d9c9ebeff2e61864fe5e827f103d1691709e4d..5fd2aef82fc18e4f8ef33fcbed62cc3cb407ce5e 100644 --- a/cpp/particles/p2p_computer.hpp +++ b/cpp/particles/p2p_computer.hpp @@ -98,6 +98,9 @@ public: rhs_part2[3+IDXC_Z] += pos_part1[3+IDXC_Z] * 4 * ww * dot_product; } + + void merge(const p2p_computer&){} + bool isEnable() const { return isActive; } diff --git a/cpp/particles/p2p_computer_empty.hpp b/cpp/particles/p2p_computer_empty.hpp index 0599dc1abb08207fcb761a534c282f8fceda5ce3..c7c0057f2fa3993900880fc37a698f5c25be9106 100644 --- a/cpp/particles/p2p_computer_empty.hpp +++ b/cpp/particles/p2p_computer_empty.hpp @@ -46,6 +46,8 @@ public: const real_number /*xshift_coef*/, const real_number /*yshift_coef*/, const real_number /*zshift_coef*/) const{ } + void merge(const p2p_computer_empty&){} + constexpr static bool isEnable() { return false; } diff --git a/cpp/particles/p2p_cylinder_collisions.hpp b/cpp/particles/p2p_cylinder_collisions.hpp new file mode 100644 index 0000000000000000000000000000000000000000..46763ddd0f7d69c1e3eded08837d332c24f4d7d8 --- /dev/null +++ b/cpp/particles/p2p_cylinder_collisions.hpp @@ -0,0 +1,77 @@ +/****************************************************************************** +* * +* Copyright 2019 Max Planck Institute for Dynamics and Self-Organization * +* * +* This file is part of bfps. * +* * +* bfps 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. * +* * +* bfps 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 bfps. If not, see <http://www.gnu.org/licenses/> * +* * +* Contact: Cristian.Lalescu@ds.mpg.de * +* * +******************************************************************************/ +#ifndef P2P_CYLINDER_GHOST_COLLISIONS_HPP +#define P2P_CYLINDER_GHOST_COLLISIONS_HPP + +#include <cstring> + +template <class real_number, class partsize_t> +class p2p_cylinder_ghost_collisions{ + long int collision_counter; + +public: + p2p_cylinder_ghost_collisions() : collision_counter(0){} + + // Copy constructor use a counter set to zero + p2p_cylinder_ghost_collisions(const p2p_cylinder_ghost_collisions&) : collision_counter(0){} + + template <int size_particle_rhs> + void init_result_array(real_number /*rhs*/[], const partsize_t /*nbParticles*/) const{ + } + + template <int size_particle_rhs> + void reduce_particles_rhs(real_number /*rhs_dst*/[], const real_number /*rhs_src*/[], const partsize_t /*nbParticles*/) const{ + } + + template <int size_particle_positions, int size_particle_rhs> + void compute_interaction(const real_number /*pos_part1*/[], real_number /*rhs_part1*/[], + const real_number /*pos_part2*/[], real_number /*rhs_part2*/[], + const real_number /*dist_pow2*/, const real_number /*cutoff*/, + const real_number /*xshift_coef*/, const real_number /*yshift_coef*/, const real_number /*zshift_coef*/){ + bool cylinders_overlap = false; + + /* TODO: check if cylinders overlap or not, set `cylinders_overlap` accordingly */ + + if(cylinders_overlap) + collision_counter += 1; + } + + void merge(const p2p_cylinder_ghost_collisions& other){ + collision_counter += other.collision_counter; + } + + constexpr static bool isEnable() { + return true; + } + + long int get_collision_counter() const{ + return collision_counter; + } + + void reset_collision_counter(){ + collision_counter = 0; + } +}; + + +#endif // P2P_CYLINDER_GHOST_COLLISIONS_HPP diff --git a/cpp/particles/p2p_distr_mpi.hpp b/cpp/particles/p2p_distr_mpi.hpp index 7ab3a8b36722b8aa03ec9f4c070a68aa1fbe1776..64b7b605c03466f4ae7bb6992db2e56de67257c4 100644 --- a/cpp/particles/p2p_distr_mpi.hpp +++ b/cpp/particles/p2p_distr_mpi.hpp @@ -530,9 +530,15 @@ public: lock_free_bool_array cells_locker(512); + std::vector<std::unique_ptr<computer_class>> computer_for_all_threads(omp_get_num_threads()-1); + for(int idxThread = 1 ; idxThread < omp_get_num_threads() ; ++idxThread){ + computer_for_all_threads[idxThread-1].reset(new computer_class(in_computer)); + } + TIMEZONE_OMP_INIT_PREPARALLEL(omp_get_max_threads()) #pragma omp parallel default(shared) { + computer_class& computer_thread = (omp_get_thread_num() == 0 ? in_computer : *computer_for_all_threads[omp_get_thread_num()-1]); #pragma omp master { while(mpiRequests.size()){ @@ -584,7 +590,7 @@ public: assert(descriptor.toCompute != nullptr); descriptor.results.reset(new real_number[NbParticlesToReceive*size_particle_rhs]); - in_computer.template init_result_array<size_particle_rhs>(descriptor.results.get(), NbParticlesToReceive); + computer_thread.template init_result_array<size_particle_rhs>(descriptor.results.get(), NbParticlesToReceive); // Compute partsize_t idxPart = 0; @@ -622,7 +628,7 @@ public: particles_positions[((*neighbors[idx_neighbor])[idx_2].first+idx_p2)*size_particle_positions + IDXC_Z], shift[idx_neighbor][IDXC_X], shift[idx_neighbor][IDXC_Y], shift[idx_neighbor][IDXC_Z]); if(dist_r2 < cutoff_radius_compute*cutoff_radius_compute){ - in_computer.template compute_interaction<size_particle_positions, size_particle_rhs>( + computer_thread.template compute_interaction<size_particle_positions, size_particle_rhs>( &descriptor.toCompute[(idxPart+idx_p1)*size_particle_positions], &descriptor.results[(idxPart+idx_p1)*size_particle_rhs], &particles_positions[((*neighbors[idx_neighbor])[idx_2].first+idx_p2)*size_particle_positions], @@ -669,7 +675,7 @@ public: NeighborDescriptor& descriptor = neigDescriptors[releasedAction.second]; assert(descriptor.isRecv == false); assert(descriptor.toRecvAndMerge != nullptr); - in_computer.template reduce_particles_rhs<size_particle_rhs>(&particles_current_rhs[particles_offset_layers[my_nb_cell_levels-descriptor.nbLevelsToExchange]*size_particle_rhs], + computer_thread.template reduce_particles_rhs<size_particle_rhs>(&particles_current_rhs[particles_offset_layers[my_nb_cell_levels-descriptor.nbLevelsToExchange]*size_particle_rhs], descriptor.toRecvAndMerge.get(), descriptor.nbParticlesToExchange); delete[] descriptor.toRecvAndMerge.release(); } @@ -680,104 +686,111 @@ public: assert(whatNext.size() == 0); assert(mpiRequests.size() == 0); - // Compute self data - for(const auto& iter_cell : my_tree){ - TIMEZONE("proceed-leaf"); - const long int currenct_cell_idx = iter_cell.first; - const std::vector<std::pair<partsize_t,partsize_t>>* intervals_ptr = &iter_cell.second; + { + computer_class& computer_thread = (omp_get_thread_num() == 0 ? in_computer : *computer_for_all_threads[omp_get_thread_num()-1]); + // Compute self data + for(const auto& iter_cell : my_tree){ + TIMEZONE("proceed-leaf"); + const long int currenct_cell_idx = iter_cell.first; + const std::vector<std::pair<partsize_t,partsize_t>>* intervals_ptr = &iter_cell.second; -#pragma omp task default(shared) firstprivate(currenct_cell_idx, intervals_ptr) - { - const std::vector<std::pair<partsize_t,partsize_t>>& intervals = (*intervals_ptr); - - cells_locker.lock(currenct_cell_idx); - - for(size_t idx_1 = 0 ; idx_1 < intervals.size() ; ++idx_1){ - // self interval - for(partsize_t idx_p1 = 0 ; idx_p1 < intervals[idx_1].second ; ++idx_p1){ - for(partsize_t idx_p2 = idx_p1+1 ; idx_p2 < intervals[idx_1].second ; ++idx_p2){ - const real_number dist_r2 = compute_distance_r2(particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions + IDXC_X], - particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions + IDXC_Y], - particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions + IDXC_Z], - particles_positions[(intervals[idx_1].first+idx_p2)*size_particle_positions + IDXC_X], - particles_positions[(intervals[idx_1].first+idx_p2)*size_particle_positions + IDXC_Y], - particles_positions[(intervals[idx_1].first+idx_p2)*size_particle_positions + IDXC_Z], - 0, 0, 0); - if(dist_r2 < cutoff_radius_compute*cutoff_radius_compute){ - in_computer.template compute_interaction<size_particle_positions,size_particle_rhs>( - &particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions], - &particles_current_rhs[(intervals[idx_1].first+idx_p1)*size_particle_rhs], - &particles_positions[(intervals[idx_1].first+idx_p2)*size_particle_positions], - &particles_current_rhs[(intervals[idx_1].first+idx_p2)*size_particle_rhs], - dist_r2, cutoff_radius_compute, 0, 0, 0); - } - } - } + #pragma omp task default(shared) firstprivate(currenct_cell_idx, intervals_ptr) + { + const std::vector<std::pair<partsize_t,partsize_t>>& intervals = (*intervals_ptr); + + cells_locker.lock(currenct_cell_idx); - // with other interval - for(size_t idx_2 = idx_1+1 ; idx_2 < intervals.size() ; ++idx_2){ + for(size_t idx_1 = 0 ; idx_1 < intervals.size() ; ++idx_1){ + // self interval for(partsize_t idx_p1 = 0 ; idx_p1 < intervals[idx_1].second ; ++idx_p1){ - for(partsize_t idx_p2 = 0 ; idx_p2 < intervals[idx_2].second ; ++idx_p2){ + for(partsize_t idx_p2 = idx_p1+1 ; idx_p2 < intervals[idx_1].second ; ++idx_p2){ const real_number dist_r2 = compute_distance_r2(particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions + IDXC_X], particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions + IDXC_Y], particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions + IDXC_Z], - particles_positions[(intervals[idx_2].first+idx_p2)*size_particle_positions + IDXC_X], - particles_positions[(intervals[idx_2].first+idx_p2)*size_particle_positions + IDXC_Y], - particles_positions[(intervals[idx_2].first+idx_p2)*size_particle_positions + IDXC_Z], + particles_positions[(intervals[idx_1].first+idx_p2)*size_particle_positions + IDXC_X], + particles_positions[(intervals[idx_1].first+idx_p2)*size_particle_positions + IDXC_Y], + particles_positions[(intervals[idx_1].first+idx_p2)*size_particle_positions + IDXC_Z], 0, 0, 0); if(dist_r2 < cutoff_radius_compute*cutoff_radius_compute){ - in_computer.template compute_interaction<size_particle_positions,size_particle_rhs>( + computer_thread.template compute_interaction<size_particle_positions,size_particle_rhs>( &particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions], &particles_current_rhs[(intervals[idx_1].first+idx_p1)*size_particle_rhs], - &particles_positions[(intervals[idx_2].first+idx_p2)*size_particle_positions], - &particles_current_rhs[(intervals[idx_2].first+idx_p2)*size_particle_rhs], + &particles_positions[(intervals[idx_1].first+idx_p2)*size_particle_positions], + &particles_current_rhs[(intervals[idx_1].first+idx_p2)*size_particle_rhs], dist_r2, cutoff_radius_compute, 0, 0, 0); } } } + + // with other interval + for(size_t idx_2 = idx_1+1 ; idx_2 < intervals.size() ; ++idx_2){ + for(partsize_t idx_p1 = 0 ; idx_p1 < intervals[idx_1].second ; ++idx_p1){ + for(partsize_t idx_p2 = 0 ; idx_p2 < intervals[idx_2].second ; ++idx_p2){ + const real_number dist_r2 = compute_distance_r2(particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions + IDXC_X], + particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions + IDXC_Y], + particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions + IDXC_Z], + particles_positions[(intervals[idx_2].first+idx_p2)*size_particle_positions + IDXC_X], + particles_positions[(intervals[idx_2].first+idx_p2)*size_particle_positions + IDXC_Y], + particles_positions[(intervals[idx_2].first+idx_p2)*size_particle_positions + IDXC_Z], + 0, 0, 0); + if(dist_r2 < cutoff_radius_compute*cutoff_radius_compute){ + computer_thread.template compute_interaction<size_particle_positions,size_particle_rhs>( + &particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions], + &particles_current_rhs[(intervals[idx_1].first+idx_p1)*size_particle_rhs], + &particles_positions[(intervals[idx_2].first+idx_p2)*size_particle_positions], + &particles_current_rhs[(intervals[idx_2].first+idx_p2)*size_particle_rhs], + dist_r2, cutoff_radius_compute, 0, 0, 0); + } + } + } + } } - } - const std::vector<std::pair<partsize_t,partsize_t>>* neighbors[27]; - long int neighbors_indexes[27]; - std::array<real_number,3> shift[27]; - const int nbNeighbors = my_tree.getNeighbors(currenct_cell_idx, neighbors, neighbors_indexes, shift, false); - - for(size_t idx_1 = 0 ; idx_1 < intervals.size() ; ++idx_1){ - // with other interval - for(int idx_neighbor = 0 ; idx_neighbor < nbNeighbors ; ++idx_neighbor){ - if(currenct_cell_idx < neighbors_indexes[idx_neighbor]){ - cells_locker.lock(neighbors_indexes[idx_neighbor]); - - for(size_t idx_2 = 0 ; idx_2 < (*neighbors[idx_neighbor]).size() ; ++idx_2){ - for(partsize_t idx_p1 = 0 ; idx_p1 < intervals[idx_1].second ; ++idx_p1){ - for(partsize_t idx_p2 = 0 ; idx_p2 < (*neighbors[idx_neighbor])[idx_2].second ; ++idx_p2){ - const real_number dist_r2 = compute_distance_r2(particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions + IDXC_X], - particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions + IDXC_Y], - particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions + IDXC_Z], - particles_positions[((*neighbors[idx_neighbor])[idx_2].first+idx_p2)*size_particle_positions + IDXC_X], - particles_positions[((*neighbors[idx_neighbor])[idx_2].first+idx_p2)*size_particle_positions + IDXC_Y], - particles_positions[((*neighbors[idx_neighbor])[idx_2].first+idx_p2)*size_particle_positions + IDXC_Z], - shift[idx_neighbor][IDXC_X], shift[idx_neighbor][IDXC_Y], shift[idx_neighbor][IDXC_Z]); - if(dist_r2 < cutoff_radius_compute*cutoff_radius_compute){ - in_computer.template compute_interaction<size_particle_positions,size_particle_rhs>( - &particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions], - &particles_current_rhs[(intervals[idx_1].first+idx_p1)*size_particle_rhs], - &particles_positions[((*neighbors[idx_neighbor])[idx_2].first+idx_p2)*size_particle_positions], - &particles_current_rhs[((*neighbors[idx_neighbor])[idx_2].first+idx_p2)*size_particle_rhs], - dist_r2, cutoff_radius_compute, shift[idx_neighbor][IDXC_X], shift[idx_neighbor][IDXC_Y], shift[idx_neighbor][IDXC_Z]); + const std::vector<std::pair<partsize_t,partsize_t>>* neighbors[27]; + long int neighbors_indexes[27]; + std::array<real_number,3> shift[27]; + const int nbNeighbors = my_tree.getNeighbors(currenct_cell_idx, neighbors, neighbors_indexes, shift, false); + + for(size_t idx_1 = 0 ; idx_1 < intervals.size() ; ++idx_1){ + // with other interval + for(int idx_neighbor = 0 ; idx_neighbor < nbNeighbors ; ++idx_neighbor){ + if(currenct_cell_idx < neighbors_indexes[idx_neighbor]){ + cells_locker.lock(neighbors_indexes[idx_neighbor]); + + for(size_t idx_2 = 0 ; idx_2 < (*neighbors[idx_neighbor]).size() ; ++idx_2){ + for(partsize_t idx_p1 = 0 ; idx_p1 < intervals[idx_1].second ; ++idx_p1){ + for(partsize_t idx_p2 = 0 ; idx_p2 < (*neighbors[idx_neighbor])[idx_2].second ; ++idx_p2){ + const real_number dist_r2 = compute_distance_r2(particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions + IDXC_X], + particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions + IDXC_Y], + particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions + IDXC_Z], + particles_positions[((*neighbors[idx_neighbor])[idx_2].first+idx_p2)*size_particle_positions + IDXC_X], + particles_positions[((*neighbors[idx_neighbor])[idx_2].first+idx_p2)*size_particle_positions + IDXC_Y], + particles_positions[((*neighbors[idx_neighbor])[idx_2].first+idx_p2)*size_particle_positions + IDXC_Z], + shift[idx_neighbor][IDXC_X], shift[idx_neighbor][IDXC_Y], shift[idx_neighbor][IDXC_Z]); + if(dist_r2 < cutoff_radius_compute*cutoff_radius_compute){ + computer_thread.template compute_interaction<size_particle_positions,size_particle_rhs>( + &particles_positions[(intervals[idx_1].first+idx_p1)*size_particle_positions], + &particles_current_rhs[(intervals[idx_1].first+idx_p1)*size_particle_rhs], + &particles_positions[((*neighbors[idx_neighbor])[idx_2].first+idx_p2)*size_particle_positions], + &particles_current_rhs[((*neighbors[idx_neighbor])[idx_2].first+idx_p2)*size_particle_rhs], + dist_r2, cutoff_radius_compute, shift[idx_neighbor][IDXC_X], shift[idx_neighbor][IDXC_Y], shift[idx_neighbor][IDXC_Z]); + } } } } + cells_locker.unlock(neighbors_indexes[idx_neighbor]); } - cells_locker.unlock(neighbors_indexes[idx_neighbor]); } } - } - cells_locker.unlock(currenct_cell_idx); + cells_locker.unlock(currenct_cell_idx); + } } } + + for(int idxThread = 1 ; idxThread < omp_get_num_threads() ; ++idxThread){ + in_computer.merge(*computer_for_all_threads[idxThread-1]); + } } }; diff --git a/cpp/particles/p2p_ghost_collisions.hpp b/cpp/particles/p2p_ghost_collisions.hpp new file mode 100644 index 0000000000000000000000000000000000000000..604ac120327729900097f39086cf331f4df3562c --- /dev/null +++ b/cpp/particles/p2p_ghost_collisions.hpp @@ -0,0 +1,72 @@ +/****************************************************************************** +* * +* Copyright 2019 Max Planck Institute for Dynamics and Self-Organization * +* * +* This file is part of bfps. * +* * +* bfps 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. * +* * +* bfps 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 bfps. If not, see <http://www.gnu.org/licenses/> * +* * +* Contact: Cristian.Lalescu@ds.mpg.de * +* * +******************************************************************************/ +#ifndef P2P_GHOST_COLLISIONS_HPP +#define P2P_GHOST_COLLISIONS_HPP + +#include <cstring> + +template <class real_number, class partsize_t> +class p2p_ghost_collisions{ + long int collision_counter; + +public: + p2p_ghost_collisions() : collision_counter(0){} + + // Copy constructor use a counter set to zero + p2p_ghost_collisions(const p2p_ghost_collisions&) : collision_counter(0){} + + template <int size_particle_rhs> + void init_result_array(real_number /*rhs*/[], const partsize_t /*nbParticles*/) const{ + } + + template <int size_particle_rhs> + void reduce_particles_rhs(real_number /*rhs_dst*/[], const real_number /*rhs_src*/[], const partsize_t /*nbParticles*/) const{ + } + + template <int size_particle_positions, int size_particle_rhs> + void compute_interaction(const real_number /*pos_part1*/[], real_number /*rhs_part1*/[], + const real_number /*pos_part2*/[], real_number /*rhs_part2*/[], + const real_number /*dist_pow2*/, const real_number /*cutoff*/, + const real_number /*xshift_coef*/, const real_number /*yshift_coef*/, const real_number /*zshift_coef*/){ + collision_counter += 1; + } + + void merge(const p2p_ghost_collisions& other){ + collision_counter += other.collision_counter; + } + + constexpr static bool isEnable() { + return true; + } + + long int get_collision_counter() const{ + return collision_counter; + } + + void reset_collision_counter(){ + collision_counter = 0; + } +}; + + +#endif // P2P_GHOST_COLLISIONS_HPP diff --git a/cpp/particles/particles_system.hpp b/cpp/particles/particles_system.hpp index 4981592c66cf691c33150ef009f07b34224b7ca0..cdb523bb69de8c4b8d27ef319b33f29b8dc71db5 100644 --- a/cpp/particles/particles_system.hpp +++ b/cpp/particles/particles_system.hpp @@ -29,6 +29,7 @@ #include <array> #include "abstract_particles_system.hpp" +#include "abstract_particles_system_with_p2p.hpp" #include "particles_distr_mpi.hpp" #include "particles_output_hdf5.hpp" #include "particles_output_mpiio.hpp" @@ -41,7 +42,7 @@ template <class partsize_t, class real_number, class field_rnumber, class field_class, class interpolator_class, int interp_neighbours, int size_particle_positions, int size_particle_rhs, class p2p_computer_class, class particles_inner_computer_class> -class particles_system : public abstract_particles_system<partsize_t, real_number> { +class particles_system : public abstract_particles_system_with_p2p<partsize_t, real_number, p2p_computer_class> { static_assert(size_particle_positions >= 3, "There should be at least the positions X,Y,Z in the state"); MPI_Comm mpi_com; @@ -402,6 +403,14 @@ public: } } } + + const p2p_computer_class& getP2PComputer() const final{ + return computer_p2p; + } + + p2p_computer_class& getP2PComputer() final{ + return computer_p2p; + } }; diff --git a/cpp/particles/particles_system_builder.hpp b/cpp/particles/particles_system_builder.hpp index 6a6f4a26f3f0f08703b1a1ed8857f2445b641ac7..dfc20dc6cac10ffcf98faf682026ea2e4cd745ee 100644 --- a/cpp/particles/particles_system_builder.hpp +++ b/cpp/particles/particles_system_builder.hpp @@ -140,7 +140,7 @@ template <class partsize_t, class field_rnumber, field_backend be, field_compone class particles_inner_computer_class, int size_particle_positions, int size_particle_rhs> struct particles_system_build_container { template <const int interpolation_size, const int spline_mode> - static std::unique_ptr<abstract_particles_system<partsize_t, particles_rnumber>> instanciate( + static std::unique_ptr<abstract_particles_system_with_p2p<partsize_t, particles_rnumber, p2p_computer_class>> instanciate( const field<field_rnumber, be, fc>* fs_field, // (field object) const kspace<be, SMOOTH>* fs_kk, // (kspace object, contains dkx, dky, dkz) const int nsteps, // to check coherency between parameters and hdf input file (nb rhs) @@ -272,7 +272,7 @@ struct particles_system_build_container { part_sys->setParticleFileLayout(generator.getParticleFileLayout()); // Return the created particles system - return std::unique_ptr<abstract_particles_system<partsize_t, particles_rnumber>>(part_sys); + return std::unique_ptr<abstract_particles_system_with_p2p<partsize_t, particles_rnumber, p2p_computer_class>>(part_sys); } }; @@ -305,7 +305,7 @@ inline std::unique_ptr<abstract_particles_system<partsize_t, particles_rnumber>> template <class partsize_t, class field_rnumber, field_backend be, field_components fc, class p2p_computer_class, class particles_inner_computer_class, class particles_rnumber = double> -inline std::unique_ptr<abstract_particles_system<partsize_t, particles_rnumber>> particles_system_builder_with_p2p( +inline std::unique_ptr<abstract_particles_system_with_p2p<partsize_t, particles_rnumber, p2p_computer_class>> particles_system_builder_with_p2p( const field<field_rnumber, be, fc>* fs_field, // (field object) const kspace<be, SMOOTH>* fs_kk, // (kspace object, contains dkx, dky, dkz) const int nsteps, // to check coherency between parameters and hdf input file (nb rhs) @@ -319,7 +319,7 @@ inline std::unique_ptr<abstract_particles_system<partsize_t, particles_rnumber>> p2p_computer_class p2p_computer, particles_inner_computer_class inner_computer, const particles_rnumber cutoff){ - return Template_double_for_if::evaluate<std::unique_ptr<abstract_particles_system<partsize_t, particles_rnumber>>, + return Template_double_for_if::evaluate<std::unique_ptr<abstract_particles_system_with_p2p<partsize_t, particles_rnumber, p2p_computer_class>>, int, 1, 11, 1, // interpolation_size int, 0, 3, 1, // spline_mode particles_system_build_container<partsize_t, field_rnumber,be,fc,particles_rnumber,