From 783cbc4c055f42de46ffaf97e1391d5d6cf4beb0 Mon Sep 17 00:00:00 2001 From: Rene Gassmoeller Date: Fri, 11 Jun 2021 13:21:33 -0400 Subject: [PATCH] Hide particle container from property pool --- include/deal.II/particles/property_pool.h | 9 ++- source/particles/particle_handler.cc | 16 ++++- source/particles/property_pool.cc | 37 +++++------- tests/particles/property_pool_03.cc | 74 ++++++++++++----------- 4 files changed, 73 insertions(+), 63 deletions(-) diff --git a/include/deal.II/particles/property_pool.h b/include/deal.II/particles/property_pool.h index 8d26b445e5..3f74a8167c 100644 --- a/include/deal.II/particles/property_pool.h +++ b/include/deal.II/particles/property_pool.h @@ -215,13 +215,12 @@ namespace Particles * This function makes sure that all internally stored memory blocks * are sorted in the same order as one would loop over the @p handles_to_sort * container. This makes sure memory access is contiguous with actual - * memory location. Because the ordering is given in the input argumet - * the complexity of this function is $O(N)$ where N is the number of - * elements in the input argument. This function creates a temporary copy of - * all currently registered memory blocks. + * memory location. Because the ordering is given in the input argument + * the complexity of this function is $O(N)$ where $N$ is the number of + * elements in the input argument. */ void - sort_memory_slots(std::vector> &handles_to_sort); + sort_memory_slots(const std::vector &handles_to_sort); private: /** diff --git a/source/particles/particle_handler.cc b/source/particles/particle_handler.cc index 52d47fc513..cdf59073e1 100644 --- a/source/particles/particle_handler.cc +++ b/source/particles/particle_handler.cc @@ -1291,7 +1291,21 @@ namespace Particles // remove_particles also calls update_cached_numbers() remove_particles(particles_out_of_cell); - property_pool->sort_memory_slots(particles); + + // now make sure particle data is sorted in order of iteration + std::vector::Handle> unsorted_handles; + unsorted_handles.reserve(local_number_of_particles); + + typename PropertyPool::Handle sorted_handle = 0; + for (auto &particles_in_cell : particles) + for (auto &particle : particles_in_cell) + { + unsorted_handles.push_back(particle); + particle = sorted_handle++; + } + + property_pool->sort_memory_slots(unsorted_handles); + } // namespace Particles diff --git a/source/particles/property_pool.cc b/source/particles/property_pool.cc index 20e48d1f96..1189a664b1 100644 --- a/source/particles/property_pool.cc +++ b/source/particles/property_pool.cc @@ -170,7 +170,7 @@ namespace Particles template void PropertyPool::sort_memory_slots( - std::vector> &handles_to_sort) + const std::vector &handles_to_sort) { std::vector> sorted_locations; std::vector> sorted_reference_locations; @@ -182,24 +182,19 @@ namespace Particles sorted_ids.reserve(ids.size()); sorted_properties.reserve(properties.size()); - Handle i = 0; - for (auto &handles_in_cell : handles_to_sort) - for (auto &handle : handles_in_cell) - { - Assert(handle != invalid_handle, - ExcMessage( - "Invalid handle detected during sorting particle memory.")); - - sorted_locations.push_back(locations[handle]); - sorted_reference_locations.push_back(reference_locations[handle]); - sorted_ids.push_back(ids[handle]); + for (auto &handle : handles_to_sort) + { + Assert(handle != invalid_handle, + ExcMessage( + "Invalid handle detected during sorting particle memory.")); - for (unsigned int j = 0; j < n_properties; ++j) - sorted_properties.push_back(properties[handle * n_properties + j]); + sorted_locations.push_back(locations[handle]); + sorted_reference_locations.push_back(reference_locations[handle]); + sorted_ids.push_back(ids[handle]); - handle = i; - ++i; - } + for (unsigned int j = 0; j < n_properties; ++j) + sorted_properties.push_back(properties[handle * n_properties + j]); + } Assert(sorted_locations.size() == locations.size() - currently_available_handles.size(), @@ -207,10 +202,10 @@ namespace Particles "Number of sorted property handles is not equal to number " "of currently registered handles.")); - locations.swap(sorted_locations); - reference_locations.swap(sorted_reference_locations); - ids.swap(sorted_ids); - properties.swap(sorted_properties); + locations = std::move(sorted_locations); + reference_locations = std::move(sorted_reference_locations); + ids = std::move(sorted_ids); + properties = std::move(sorted_properties); currently_available_handles.clear(); } diff --git a/tests/particles/property_pool_03.cc b/tests/particles/property_pool_03.cc index 64ada7b132..532e745112 100644 --- a/tests/particles/property_pool_03.cc +++ b/tests/particles/property_pool_03.cc @@ -35,60 +35,62 @@ test() const unsigned int n_properties = 3; Particles::PropertyPool pool(n_properties); - std::vector< - std::vector::Handle>> + std::vector::Handle> particle_handles; - particle_handles.resize(2); // Allocate some space in non-contigous locations - particle_handles[1].push_back(pool.register_particle()); - particle_handles[0].push_back(pool.register_particle()); - particle_handles[1].push_back(pool.register_particle()); - particle_handles[0].push_back(pool.register_particle()); - particle_handles[1].push_back(pool.register_particle()); - particle_handles[0].push_back(pool.register_particle()); + particle_handles.push_back(pool.register_particle()); + particle_handles.insert(particle_handles.begin(), pool.register_particle()); + particle_handles.push_back(pool.register_particle()); + particle_handles.insert(particle_handles.begin(), pool.register_particle()); + particle_handles.push_back(pool.register_particle()); + particle_handles.insert(particle_handles.begin(), pool.register_particle()); unsigned int i = 0; - for (auto &particles_in_cell : particle_handles) - for (auto &particle : particles_in_cell) - pool.set_id(particle, i++); + for (auto &particle : particle_handles) + pool.set_id(particle, i++); - for (const auto &particles_in_cell : particle_handles) - for (const auto &particle : particles_in_cell) - deallog << "Before removal unsorted ID: " << pool.get_id(particle) - << ". Handle: " << particle << std::endl; + for (const auto &particle : particle_handles) + deallog << "Before removal unsorted ID: " << pool.get_id(particle) + << ". Handle: " << particle << std::endl; pool.sort_memory_slots(particle_handles); - for (const auto &particles_in_cell : particle_handles) - for (const auto &particle : particles_in_cell) - deallog << "Before removal sorted ID: " << pool.get_id(particle) - << ". Handle: " << particle << std::endl; + typename Particles::PropertyPool::Handle h = 0; + for (auto &particle : particle_handles) + particle = h++; + + for (const auto &particle : particle_handles) + deallog << "Before removal sorted ID: " << pool.get_id(particle) + << ". Handle: " << particle << std::endl; // Deallocate some space in the same way the particle handler would // remove particles - pool.deregister_particle(particle_handles[1][1]); - pool.deregister_particle(particle_handles[0][2]); + pool.deregister_particle(particle_handles[2]); + pool.deregister_particle(particle_handles[3]); + + particle_handles[2] = particle_handles.back(); + particle_handles.resize(particle_handles.size() - 1); - particle_handles[1][1] = particle_handles[1].back(); - particle_handles[1].resize(particle_handles[1].size() - 1); - particle_handles[0].resize(particle_handles[0].size() - 1); + particle_handles[3] = particle_handles.back(); + particle_handles.resize(particle_handles.size() - 1); - for (const auto &particles_in_cell : particle_handles) - for (const auto &particle : particles_in_cell) - deallog << "After removal unsorted ID: " << pool.get_id(particle) - << ". Handle: " << particle << std::endl; + for (const auto &particle : particle_handles) + deallog << "After removal unsorted ID: " << pool.get_id(particle) + << ". Handle: " << particle << std::endl; pool.sort_memory_slots(particle_handles); - for (const auto &particles_in_cell : particle_handles) - for (const auto &particle : particles_in_cell) - deallog << "After removal sorted ID: " << pool.get_id(particle) - << ". Handle: " << particle << std::endl; + h = 0; + for (auto &particle : particle_handles) + particle = h++; + + for (const auto &particle : particle_handles) + deallog << "After removal sorted ID: " << pool.get_id(particle) + << ". Handle: " << particle << std::endl; - for (auto &particles_in_cell : particle_handles) - for (auto &particle : particles_in_cell) - pool.deregister_particle(particle); + for (auto &particle : particle_handles) + pool.deregister_particle(particle); } deallog << "OK" << std::endl; -- 2.39.5