Cabana 0.8.0-dev
 
Loading...
Searching...
No Matches
Cabana_Remove.hpp
Go to the documentation of this file.
1/****************************************************************************
2 * Copyright (c) 2018-2023 by the Cabana authors *
3 * All rights reserved. *
4 * *
5 * This file is part of the Cabana library. Cabana is distributed under a *
6 * BSD 3-clause license. For the licensing terms see the LICENSE file in *
7 * the top-level directory. *
8 * *
9 * SPDX-License-Identifier: BSD-3-Clause *
10 ****************************************************************************/
11
16#ifndef CABANA_REMOVE_HPP
17#define CABANA_REMOVE_HPP
18
19#include <Cabana_AoSoA.hpp>
20#include <Cabana_DeepCopy.hpp>
21#include <Cabana_Slice.hpp>
22
23#include <Kokkos_Core.hpp>
24namespace Cabana
25{
26//---------------------------------------------------------------------------//
39template <class ExecutionSpace, class KeepView, class ParticleAoSoA>
40void remove( const ExecutionSpace& exec_space, const int num_keep,
41 const KeepView& keep_particle, ParticleAoSoA& particles,
42 const int num_particles_ignore = 0,
43 const bool shrink_to_fit = true )
44{
45 using memory_space = typename KeepView::memory_space;
46
47 // Determine the empty particle positions in the compaction zone.
48 int num_particles = particles.size();
49 // This View is either empty indices to be filled or the created particle
50 // indices, depending on the ratio of allocated space to the number
51 // created.
52 Kokkos::View<int*, memory_space> indices(
53 Kokkos::ViewAllocateWithoutInitializing( "empty_or_filled" ),
54 std::min( num_particles - num_particles_ignore - num_keep, num_keep ) );
55
56 int new_num_particles = num_particles_ignore + num_keep;
57 // parallel_scan will break if not keeping any particles.
58 if ( num_keep > 0 )
59 {
60 Kokkos::parallel_scan(
61 "Cabana::remove::FindEmpty",
62 Kokkos::RangePolicy<ExecutionSpace>( exec_space, 0, num_keep ),
63 KOKKOS_LAMBDA( const int i, int& count, const bool final_pass ) {
64 if ( !keep_particle( i ) )
65 {
66 if ( final_pass )
67 {
68 indices( count ) = i + num_particles_ignore;
69 }
70 ++count;
71 }
72 } );
73 Kokkos::fence();
74
75 // Compact the list so the it only has real particles.
76 Kokkos::parallel_scan(
77 "Cabana::remove::RemoveEmpty",
78 Kokkos::RangePolicy<ExecutionSpace>( exec_space, new_num_particles,
79 num_particles ),
80 KOKKOS_LAMBDA( const int i, int& count, const bool final_pass ) {
81 if ( keep_particle( i - num_particles_ignore ) )
82 {
83 if ( final_pass )
84 {
85 particles.setTuple( indices( count ),
86 particles.getTuple( i ) );
87 }
88 ++count;
89 }
90 } );
91 }
92
93 particles.resize( new_num_particles );
94 if ( shrink_to_fit )
95 particles.shrinkToFit();
96}
97
98} // end namespace Cabana
99
100#endif // end CABANA_REMOVE_HPP
Array-of-Struct-of-Arrays particle data structure.
AoSoA and slice extensions for Kokkos deep copy and mirrors.
Slice a single particle property from an AoSoA.
Core: particle data structures and algorithms.
Definition Cabana_AoSoA.hpp:36
void remove(const ExecutionSpace &exec_space, const int num_keep, const KeepView &keep_particle, ParticleAoSoA &particles, const int num_particles_ignore=0, const bool shrink_to_fit=true)
Filter out empty/unneeded particles.
Definition Cabana_Remove.hpp:40