16#ifndef CABANA_LINKEDCELLLIST_HPP
17#define CABANA_LINKEDCELLLIST_HPP
23#include <impl/Cabana_CartesianGrid.hpp>
25#include <Kokkos_Core.hpp>
26#include <Kokkos_Profiling_ScopedRegion.hpp>
27#include <Kokkos_ScatterView.hpp>
36template <
class Scalar>
40 Impl::CartesianGrid<Scalar>
grid;
53 const Scalar cell_size_ratio,
const Scalar grid_min[3],
54 const Scalar grid_max[3] )
56 Scalar dx = neighborhood_radius * cell_size_ratio;
57 grid = Impl::CartesianGrid<Scalar>(
58 grid_min[0], grid_min[1], grid_min[2], grid_max[0], grid_max[1],
59 grid_max[2], dx, dx, dx );
66 KOKKOS_INLINE_FUNCTION
67 void getCells(
const int cell,
int& imin,
int& imax,
int& jmin,
int& jmax,
68 int& kmin,
int& kmax )
const
71 grid.ijkBinIndex( cell, i, j, k );
93template <
class MemorySpace,
class Scalar =
double>
104 static_assert( Impl::deprecated( Kokkos::is_device<MemorySpace>() ) );
107 using device_type [[deprecated]] =
typename memory_space::device_type;
135 template <
class PositionType>
137 PositionType positions,
const Scalar grid_delta[3],
138 const Scalar grid_min[3],
const Scalar grid_max[3],
140 Kokkos::is_view<PositionType>::value ),
143 , _end(
size( positions ) )
144 , _grid( grid_min[0], grid_min[1], grid_min[2], grid_max[0],
145 grid_max[1], grid_max[2], grid_delta[0], grid_delta[1],
147 , _cell_stencil( grid_delta[0], 1.0, grid_min, grid_max )
150 std::size_t np =
size( positions );
152 build( positions, 0, np );
171 template <
class PositionType>
173 PositionType positions,
const std::size_t begin,
const std::size_t end,
174 const Scalar grid_delta[3],
const Scalar grid_min[3],
175 const Scalar grid_max[3],
177 Kokkos::is_view<PositionType>::value ),
181 , _grid( grid_min[0], grid_min[1], grid_min[2], grid_max[0],
182 grid_max[1], grid_max[2], grid_delta[0], grid_delta[1],
184 , _cell_stencil( grid_delta[0], 1.0, grid_min, grid_max )
188 build( positions, begin, end );
203 template <
class PositionType>
205 PositionType positions,
const Scalar grid_delta[3],
206 const Scalar grid_min[3],
const Scalar grid_max[3],
207 const Scalar neighborhood_radius,
const Scalar cell_size_ratio = 1,
209 Kokkos::is_view<PositionType>::value ),
212 , _end(
size( positions ) )
213 , _grid( grid_min[0], grid_min[1], grid_min[2], grid_max[0],
214 grid_max[1], grid_max[2], grid_delta[0], grid_delta[1],
216 , _cell_stencil( neighborhood_radius, cell_size_ratio, grid_min,
220 std::size_t np =
size( positions );
222 build( positions, 0, np );
243 template <
class PositionType>
245 PositionType positions,
const std::size_t begin,
const std::size_t end,
246 const Scalar grid_delta[3],
const Scalar grid_min[3],
247 const Scalar grid_max[3],
const Scalar neighborhood_radius,
248 const Scalar cell_size_ratio = 1,
250 Kokkos::is_view<PositionType>::value ),
254 , _grid( grid_min[0], grid_min[1], grid_min[2], grid_max[0],
255 grid_max[1], grid_max[2], grid_delta[0], grid_delta[1],
257 , _cell_stencil( neighborhood_radius, cell_size_ratio, grid_min,
262 build( positions, begin, end );
266 KOKKOS_INLINE_FUNCTION
270 KOKKOS_INLINE_FUNCTION
274 KOKKOS_INLINE_FUNCTION
281 KOKKOS_INLINE_FUNCTION
289 KOKKOS_INLINE_FUNCTION
290 int numBin(
const int dim )
const {
return _grid.numBin( dim ); }
302 KOKKOS_INLINE_FUNCTION
305 return _grid.cardinalCellIndex( i, j, k );
318 KOKKOS_INLINE_FUNCTION
319 void ijkBinIndex(
const int cardinal,
int& i,
int& j,
int& k )
const
321 _grid.ijkBinIndex( cardinal, i, j, k );
331 KOKKOS_INLINE_FUNCTION
332 int binSize(
const int i,
const int j,
const int k )
const
344 KOKKOS_INLINE_FUNCTION
356 KOKKOS_INLINE_FUNCTION
359 return _bin_data.permutation( particle_id );
365 KOKKOS_INLINE_FUNCTION
366 std::size_t
rangeBegin()
const {
return _bin_data.rangeBegin(); }
371 KOKKOS_INLINE_FUNCTION
372 std::size_t
rangeEnd()
const {
return _bin_data.rangeEnd(); }
378 KOKKOS_INLINE_FUNCTION
401 template <
class ExecutionSpace,
class PositionType>
402 void build( ExecutionSpace, PositionType positions,
const std::size_t begin,
403 const std::size_t end )
405 Kokkos::Profiling::ScopedRegion region(
406 "Cabana::LinkedCellList::build" );
409 assert( end >= begin );
410 assert( end <=
size( positions ) );
415 if ( _counts.extent( 0 ) != ncell )
417 Kokkos::resize( _counts, ncell );
418 Kokkos::resize( _offsets, ncell );
420 std::size_t nparticles = end - begin;
421 if ( _permutes.extent( 0 ) != nparticles )
423 Kokkos::resize( _permutes, nparticles );
428 auto counts = _counts;
429 auto offsets = _offsets;
430 auto permutes = _permutes;
433 Kokkos::RangePolicy<ExecutionSpace> particle_range( begin, end );
434 Kokkos::deep_copy( _counts, 0 );
435 auto counts_sv = Kokkos::Experimental::create_scatter_view( _counts );
436 auto cell_count = KOKKOS_LAMBDA(
const std::size_t p )
439 grid.locatePoint( positions( p, 0 ), positions( p, 1 ),
440 positions( p, 2 ), i, j, k );
441 auto counts_data = counts_sv.access();
442 counts_data( grid.cardinalCellIndex( i, j, k ) ) += 1;
444 Kokkos::parallel_for(
"Cabana::LinkedCellList::build::cell_count",
445 particle_range, cell_count );
447 Kokkos::Experimental::contribute( _counts, counts_sv );
450 Kokkos::RangePolicy<ExecutionSpace> cell_range( 0, ncell );
451 auto offset_scan = KOKKOS_LAMBDA(
const std::size_t c,
int&
update,
452 const bool final_pass )
458 Kokkos::parallel_scan(
"Cabana::LinkedCellList::build::offset_scan",
459 cell_range, offset_scan );
463 Kokkos::deep_copy( _counts, 0 );
466 auto create_permute = KOKKOS_LAMBDA(
const std::size_t p )
469 grid.locatePoint( positions( p, 0 ), positions( p, 1 ),
470 positions( p, 2 ), i, j, k );
471 auto cell_id = grid.cardinalCellIndex( i, j, k );
472 int c = Kokkos::atomic_fetch_add( &counts( cell_id ), 1 );
473 permutes( offsets( cell_id ) + c ) = p;
475 Kokkos::parallel_for(
"Cabana::LinkedCellList::build::create_permute",
476 particle_range, create_permute );
500 template <
class PositionType>
501 void build( PositionType positions,
const std::size_t begin,
502 const std::size_t end )
515 template <
class PositionType>
516 void build( PositionType positions )
518 build( positions, 0,
size( positions ) );
526 Kokkos::parallel_for(
527 "Cabana::LinkedCellList::storeBinIndices",
528 Kokkos::RangePolicy<execution_space>( 0,
totalBins() ), *
this );
540 KOKKOS_INLINE_FUNCTION
543 assert( particle_index >=
static_cast<int>( _begin ) );
544 assert( particle_index <
static_cast<int>( _end ) );
545 return _particle_bins( particle_index - _begin );
555 ijkBinIndex( i, bin_ijk[0], bin_ijk[1], bin_ijk[2] );
556 auto offset =
binOffset( bin_ijk[0], bin_ijk[1], bin_ijk[2] );
557 auto size =
binSize( bin_ijk[0], bin_ijk[1], bin_ijk[2] );
558 for (
size_t p = offset; p < offset +
size; ++p )
562 _particle_bins( p ) = i;
580 KOKKOS_INLINE_FUNCTION
586 KOKKOS_INLINE_FUNCTION
588 int& jmax,
int& kmin,
int& kmax )
const
590 _cell_stencil.getCells( cell, imin, imax, jmin, jmax, kmin, kmax );
597 KOKKOS_INLINE_FUNCTION
614 Impl::CartesianGrid<Scalar> _grid;
626 void allocate(
const int ncell,
const int nparticles )
629 Kokkos::view_alloc( Kokkos::WithoutInitializing,
"counts" ),
632 Kokkos::view_alloc( Kokkos::WithoutInitializing,
"offsets" ),
635 Kokkos::view_alloc( Kokkos::WithoutInitializing,
"permutes" ),
640 Kokkos::view_alloc( Kokkos::WithoutInitializing,
"counts" ),
649template <
class MemorySpace,
class PositionType,
class Scalar>
651 const Scalar grid_min[3],
const Scalar grid_max[3] )
661template <
class MemorySpace,
class PositionType,
class Scalar>
663 const std::size_t end,
const Scalar grid_delta[3],
664 const Scalar grid_min[3],
const Scalar grid_max[3] )
667 positions, begin, end, grid_delta, grid_min, grid_max );
675template <
class MemorySpace,
class PositionType,
class Scalar>
677 const Scalar grid_min[3],
const Scalar grid_max[3],
678 const Scalar neighborhood_radius,
679 const Scalar cell_size_ratio = 1.0 )
682 grid_max, neighborhood_radius,
691template <
class MemorySpace,
class PositionType,
class Scalar>
693 const std::size_t end,
const Scalar grid_delta[3],
694 const Scalar grid_min[3],
const Scalar grid_max[3],
695 const Scalar neighborhood_radius,
696 const Scalar cell_size_ratio = 1.0 )
699 positions, begin, end, grid_delta, grid_min, grid_max,
700 neighborhood_radius, cell_size_ratio );
706struct is_linked_cell_list_impl :
public std::false_type
710template <
typename MemorySpace,
typename Scalar>
711struct is_linked_cell_list_impl<
LinkedCellList<MemorySpace, Scalar>>
712 :
public std::true_type
720 :
public is_linked_cell_list_impl<typename std::remove_cv<T>::type>::type
736template <
class LinkedCellListType,
class PositionType>
738 LinkedCellListType& linked_cell_list, PositionType& positions,
742 Kokkos::is_view<PositionType>::value ) ),
745 permute( linked_cell_list.binningData(), positions );
748 linked_cell_list.update(
true );
750 linked_cell_list.storeParticleBins();
755template <
class MemorySpace,
typename Scalar>
765 KOKKOS_INLINE_FUNCTION
static std::size_t
768 std::size_t total_n = 0;
777 KOKKOS_INLINE_FUNCTION
780 std::size_t max_n = 0;
790 KOKKOS_INLINE_FUNCTION
static std::size_t
794 int imin, imax, jmin, jmax, kmin, kmax;
796 jmin, jmax, kmin, kmax );
799 for (
int i = imin; i < imax; ++i )
800 for (
int j = jmin; j < jmax; ++j )
801 for (
int k = kmin; k < kmax; ++k )
803 total_count += list.
binSize( i, j, k );
810 KOKKOS_INLINE_FUNCTION
static std::size_t
812 const std::size_t neighbor_index )
814 std::size_t total_count = 0;
815 std::size_t previous_count = 0;
816 int imin, imax, jmin, jmax, kmin, kmax;
818 jmin, jmax, kmin, kmax );
821 for (
int i = imin; i < imax; ++i )
822 for (
int j = jmin; j < jmax; ++j )
823 for (
int k = kmin; k < kmax; ++k )
825 total_count += list.
binSize( i, j, k );
827 if ( total_count > neighbor_index )
829 int particle_id = list.
binOffset( i, j, k ) +
830 ( neighbor_index - previous_count );
833 previous_count = total_count;
Slice a single particle property from an AoSoA.
Sorting and binning built on Kokkos BinSort.
Data describing the bin sizes and offsets resulting from a binning operation.
Definition Cabana_Sort.hpp:39
Data describing the bin sizes and offsets resulting from a binning operation on a 3d regular Cartesia...
Definition Cabana_LinkedCellList.hpp:95
Kokkos::View< size_type *, memory_space > OffsetView
Offset view type.
Definition Cabana_LinkedCellList.hpp:116
LinkedCellList(PositionType positions, const std::size_t begin, const std::size_t end, const Scalar grid_delta[3], const Scalar grid_min[3], const Scalar grid_max[3], typename std::enable_if<(is_slice< PositionType >::value||Kokkos::is_view< PositionType >::value), int >::type *=0)
Partial range constructor.
Definition Cabana_LinkedCellList.hpp:172
KOKKOS_INLINE_FUNCTION std::size_t getParticleBegin() const
Beginning of binned range.
Definition Cabana_LinkedCellList.hpp:271
void build(ExecutionSpace, PositionType positions, const std::size_t begin, const std::size_t end)
Build the linked cell list with a subset of particles.
Definition Cabana_LinkedCellList.hpp:402
void build(PositionType positions)
Build the linked cell list with all particles.
Definition Cabana_LinkedCellList.hpp:516
LinkedCellList(PositionType positions, const Scalar grid_delta[3], const Scalar grid_min[3], const Scalar grid_max[3], const Scalar neighborhood_radius, const Scalar cell_size_ratio=1, typename std::enable_if<(is_slice< PositionType >::value||Kokkos::is_view< PositionType >::value), int >::type *=0)
Explicit stencil constructor.
Definition Cabana_LinkedCellList.hpp:204
KOKKOS_INLINE_FUNCTION auto getParticleBin(const int particle_index) const
Get the bin cell index of the input particle.
Definition Cabana_LinkedCellList.hpp:541
KOKKOS_INLINE_FUNCTION int binSize(const int i, const int j, const int k) const
Given a bin get the number of particles it contains.
Definition Cabana_LinkedCellList.hpp:332
Kokkos::View< int *, memory_space > CountView
Binning view type.
Definition Cabana_LinkedCellList.hpp:114
KOKKOS_INLINE_FUNCTION int numParticles() const
Number of binned particles.
Definition Cabana_LinkedCellList.hpp:267
KOKKOS_INLINE_FUNCTION size_type cardinalBinIndex(const int i, const int j, const int k) const
Given the ijk index of a bin get its cardinal index.
Definition Cabana_LinkedCellList.hpp:303
KOKKOS_INLINE_FUNCTION void getStencilCells(const int cell, int &imin, int &imax, int &jmin, int &jmax, int &kmin, int &kmax) const
Get the cell indices for the stencil about cell.
Definition Cabana_LinkedCellList.hpp:587
KOKKOS_INLINE_FUNCTION stencil_type cellStencil() const
Get the linked cell stencil.
Definition Cabana_LinkedCellList.hpp:379
KOKKOS_INLINE_FUNCTION size_type binOffset(const int i, const int j, const int k) const
Given a bin get the particle index at which it sorts.
Definition Cabana_LinkedCellList.hpp:345
Cabana::LinkedCellStencil< Scalar > stencil_type
Stencil type.
Definition Cabana_LinkedCellList.hpp:118
typename MemorySpace::memory_space memory_space
Memory space.
Definition Cabana_LinkedCellList.hpp:102
KOKKOS_INLINE_FUNCTION auto getParticle(const int offset) const
Get a candidate neighbor particle at a given binned offset.
Definition Cabana_LinkedCellList.hpp:598
KOKKOS_INLINE_FUNCTION size_type permutation(const int particle_id) const
Given a local particle id in the binned layout, get the id of the particle in the old (unbinned) layo...
Definition Cabana_LinkedCellList.hpp:357
LinkedCellList(PositionType positions, const Scalar grid_delta[3], const Scalar grid_min[3], const Scalar grid_max[3], typename std::enable_if<(is_slice< PositionType >::value||Kokkos::is_view< PositionType >::value), int >::type *=0)
Simple constructor.
Definition Cabana_LinkedCellList.hpp:136
typename memory_space::size_type size_type
Memory space size type.
Definition Cabana_LinkedCellList.hpp:111
KOKKOS_INLINE_FUNCTION std::size_t getParticleEnd() const
End of binned range.
Definition Cabana_LinkedCellList.hpp:275
KOKKOS_INLINE_FUNCTION auto sorted() const
Definition Cabana_LinkedCellList.hpp:581
LinkedCellList()
Default constructor.
Definition Cabana_LinkedCellList.hpp:123
auto getParticleBins() const
Get the bin cell index for each binned particle.
Definition Cabana_LinkedCellList.hpp:535
KOKKOS_INLINE_FUNCTION int totalBins() const
Get the total number of bins.
Definition Cabana_LinkedCellList.hpp:282
void update(const bool sorted)
Definition Cabana_LinkedCellList.hpp:575
KOKKOS_INLINE_FUNCTION void ijkBinIndex(const int cardinal, int &i, int &j, int &k) const
Given the cardinal index of a bin get its ijk indices.
Definition Cabana_LinkedCellList.hpp:319
void build(PositionType positions, const std::size_t begin, const std::size_t end)
Build the linked cell list with a subset of particles.
Definition Cabana_LinkedCellList.hpp:501
KOKKOS_FUNCTION void operator()(const int i) const
Determines which particles belong to bin i.
Definition Cabana_LinkedCellList.hpp:552
LinkedCellList(PositionType positions, const std::size_t begin, const std::size_t end, const Scalar grid_delta[3], const Scalar grid_min[3], const Scalar grid_max[3], const Scalar neighborhood_radius, const Scalar cell_size_ratio=1, typename std::enable_if<(is_slice< PositionType >::value||Kokkos::is_view< PositionType >::value), int >::type *=0)
Explicit stencil and partial range constructor.
Definition Cabana_LinkedCellList.hpp:244
typename memory_space::execution_space execution_space
Default execution space.
Definition Cabana_LinkedCellList.hpp:109
BinningData< MemorySpace > binningData() const
Get the 1d bin data.
Definition Cabana_LinkedCellList.hpp:385
KOKKOS_INLINE_FUNCTION std::size_t rangeBegin() const
The beginning particle index binned by the linked cell list.
Definition Cabana_LinkedCellList.hpp:366
void storeParticleBins()
Store the bin cell index for each binned particle.
Definition Cabana_LinkedCellList.hpp:524
KOKKOS_INLINE_FUNCTION std::size_t rangeEnd() const
The ending particle index binned by the linked cell list.
Definition Cabana_LinkedCellList.hpp:372
KOKKOS_INLINE_FUNCTION int numBin(const int dim) const
Get the number of bins in a given dimension.
Definition Cabana_LinkedCellList.hpp:290
MemorySpace memory_space
Kokkos memory space.
Definition Cabana_LinkedCellList.hpp:760
static KOKKOS_INLINE_FUNCTION std::size_t numNeighbor(const list_type &list, const std::size_t particle_index)
Get the number of neighbors for a given particle index.
Definition Cabana_LinkedCellList.hpp:791
LinkedCellList< MemorySpace, Scalar > list_type
Neighbor list type.
Definition Cabana_LinkedCellList.hpp:762
static KOKKOS_INLINE_FUNCTION std::size_t maxNeighbor(const list_type &list)
Get the maximum number of neighbors per particles.
Definition Cabana_LinkedCellList.hpp:778
static KOKKOS_INLINE_FUNCTION std::size_t getNeighbor(const list_type &list, const std::size_t particle_index, const std::size_t neighbor_index)
Definition Cabana_LinkedCellList.hpp:811
static KOKKOS_INLINE_FUNCTION std::size_t totalNeighbor(const list_type &list)
Get the total number of neighbors across all particles.
Definition Cabana_LinkedCellList.hpp:766
Neighbor list interface. Provides an interface callable at the functor level that gives access to nei...
Definition Cabana_NeighborList.hpp:114
static KOKKOS_INLINE_FUNCTION std::size_t numNeighbor(const NeighborListType &list, const std::size_t particle_index)
Get the number of neighbors for a given particle index.
static KOKKOS_INLINE_FUNCTION std::size_t totalNeighbor(const NeighborListType &list)
Get the total number of neighbors across all particles.
Core: particle data structures and algorithms.
Definition Cabana_AoSoA.hpp:36
auto size(SliceType slice, typename std::enable_if< is_slice< SliceType >::value, int >::type *=0)
Check slice size (differs from Kokkos View).
Definition Cabana_Slice.hpp:1012
void permute(LinkedCellListType &linked_cell_list, PositionType &positions, typename std::enable_if<(is_linked_cell_list< LinkedCellListType >::value &&(is_aosoa< PositionType >::value||is_slice< PositionType >::value||Kokkos::is_view< PositionType >::value)), int >::type *=0)
Given a linked cell list permute positions.
Definition Cabana_LinkedCellList.hpp:737
auto createLinkedCellList(PositionType positions, const Scalar grid_delta[3], const Scalar grid_min[3], const Scalar grid_max[3])
Creation function for linked cell list.
Definition Cabana_LinkedCellList.hpp:650
Stencil of cells surrounding each cell.
Definition Cabana_LinkedCellList.hpp:38
int cell_range
Range of cells to search based on cutoff.
Definition Cabana_LinkedCellList.hpp:46
LinkedCellStencil(const Scalar neighborhood_radius, const Scalar cell_size_ratio, const Scalar grid_min[3], const Scalar grid_max[3])
Constructor.
Definition Cabana_LinkedCellList.hpp:52
int max_cells
Maximum total cells.
Definition Cabana_LinkedCellList.hpp:44
int max_cells_dir
Maximum cells per dimension.
Definition Cabana_LinkedCellList.hpp:42
LinkedCellStencil()
Default Constructor.
Definition Cabana_LinkedCellList.hpp:49
Impl::CartesianGrid< Scalar > grid
Background grid.
Definition Cabana_LinkedCellList.hpp:40
KOKKOS_INLINE_FUNCTION void getCells(const int cell, int &imin, int &imax, int &jmin, int &jmax, int &kmin, int &kmax) const
Given a cell, get the index bounds of the cell stencil.
Definition Cabana_LinkedCellList.hpp:67
Definition Cabana_Types.hpp:88
AoSoA static type checker.
Definition Cabana_AoSoA.hpp:61
LinkedCellList static type checker.
Definition Cabana_LinkedCellList.hpp:721
Slice static type checker.
Definition Cabana_Slice.hpp:861