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>
99 static_assert( Kokkos::is_memory_space<MemorySpace>() );
128 template <
class PositionType>
130 PositionType positions,
const Scalar grid_delta[3],
131 const Scalar grid_min[3],
const Scalar grid_max[3],
133 Kokkos::is_view<PositionType>::value ),
136 , _end(
size( positions ) )
137 , _grid( grid_min[0], grid_min[1], grid_min[2], grid_max[0],
138 grid_max[1], grid_max[2], grid_delta[0], grid_delta[1],
140 , _cell_stencil( grid_delta[0], 1.0, grid_min, grid_max )
143 std::size_t np =
size( positions );
145 build( positions, 0, np );
164 template <
class PositionType>
166 PositionType positions,
const std::size_t begin,
const std::size_t end,
167 const Scalar grid_delta[3],
const Scalar grid_min[3],
168 const Scalar grid_max[3],
170 Kokkos::is_view<PositionType>::value ),
174 , _grid( grid_min[0], grid_min[1], grid_min[2], grid_max[0],
175 grid_max[1], grid_max[2], grid_delta[0], grid_delta[1],
177 , _cell_stencil( grid_delta[0], 1.0, grid_min, grid_max )
181 build( positions, begin, end );
196 template <
class PositionType>
198 PositionType positions,
const Scalar grid_delta[3],
199 const Scalar grid_min[3],
const Scalar grid_max[3],
200 const Scalar neighborhood_radius,
const Scalar cell_size_ratio = 1,
202 Kokkos::is_view<PositionType>::value ),
205 , _end(
size( positions ) )
206 , _grid( grid_min[0], grid_min[1], grid_min[2], grid_max[0],
207 grid_max[1], grid_max[2], grid_delta[0], grid_delta[1],
209 , _cell_stencil( neighborhood_radius, cell_size_ratio, grid_min,
213 std::size_t np =
size( positions );
215 build( positions, 0, np );
236 template <
class PositionType>
238 PositionType positions,
const std::size_t begin,
const std::size_t end,
239 const Scalar grid_delta[3],
const Scalar grid_min[3],
240 const Scalar grid_max[3],
const Scalar neighborhood_radius,
241 const Scalar cell_size_ratio = 1,
243 Kokkos::is_view<PositionType>::value ),
247 , _grid( grid_min[0], grid_min[1], grid_min[2], grid_max[0],
248 grid_max[1], grid_max[2], grid_delta[0], grid_delta[1],
250 , _cell_stencil( neighborhood_radius, cell_size_ratio, grid_min,
255 build( positions, begin, end );
259 KOKKOS_INLINE_FUNCTION
263 KOKKOS_INLINE_FUNCTION
267 KOKKOS_INLINE_FUNCTION
274 KOKKOS_INLINE_FUNCTION
282 KOKKOS_INLINE_FUNCTION
283 int numBin(
const int dim )
const {
return _grid.numBin( dim ); }
295 KOKKOS_INLINE_FUNCTION
298 return _grid.cardinalCellIndex( i, j, k );
311 KOKKOS_INLINE_FUNCTION
312 void ijkBinIndex(
const int cardinal,
int& i,
int& j,
int& k )
const
314 _grid.ijkBinIndex( cardinal, i, j, k );
324 KOKKOS_INLINE_FUNCTION
325 int binSize(
const int i,
const int j,
const int k )
const
337 KOKKOS_INLINE_FUNCTION
349 KOKKOS_INLINE_FUNCTION
352 return _bin_data.permutation( particle_id );
358 KOKKOS_INLINE_FUNCTION
359 std::size_t
rangeBegin()
const {
return _bin_data.rangeBegin(); }
364 KOKKOS_INLINE_FUNCTION
365 std::size_t
rangeEnd()
const {
return _bin_data.rangeEnd(); }
371 KOKKOS_INLINE_FUNCTION
394 template <
class ExecutionSpace,
class PositionType>
395 void build( ExecutionSpace, PositionType positions,
const std::size_t begin,
396 const std::size_t end )
398 Kokkos::Profiling::ScopedRegion region(
399 "Cabana::LinkedCellList::build" );
402 assert( end >= begin );
403 assert( end <=
size( positions ) );
408 if ( _counts.extent( 0 ) != ncell )
410 Kokkos::resize( _counts, ncell );
411 Kokkos::resize( _offsets, ncell );
413 std::size_t nparticles = end - begin;
414 if ( _permutes.extent( 0 ) != nparticles )
416 Kokkos::resize( _permutes, nparticles );
421 auto counts = _counts;
422 auto offsets = _offsets;
423 auto permutes = _permutes;
426 Kokkos::RangePolicy<ExecutionSpace> particle_range( begin, end );
427 Kokkos::deep_copy( _counts, 0 );
428 auto counts_sv = Kokkos::Experimental::create_scatter_view( _counts );
429 auto cell_count = KOKKOS_LAMBDA(
const std::size_t p )
432 grid.locatePoint( positions( p, 0 ), positions( p, 1 ),
433 positions( p, 2 ), i, j, k );
434 auto counts_data = counts_sv.access();
435 counts_data( grid.cardinalCellIndex( i, j, k ) ) += 1;
437 Kokkos::parallel_for(
"Cabana::LinkedCellList::build::cell_count",
438 particle_range, cell_count );
440 Kokkos::Experimental::contribute( _counts, counts_sv );
443 Kokkos::RangePolicy<ExecutionSpace> cell_range( 0, ncell );
444 auto offset_scan = KOKKOS_LAMBDA(
const std::size_t c,
int&
update,
445 const bool final_pass )
451 Kokkos::parallel_scan(
"Cabana::LinkedCellList::build::offset_scan",
452 cell_range, offset_scan );
456 Kokkos::deep_copy( _counts, 0 );
459 auto create_permute = KOKKOS_LAMBDA(
const std::size_t p )
462 grid.locatePoint( positions( p, 0 ), positions( p, 1 ),
463 positions( p, 2 ), i, j, k );
464 auto cell_id = grid.cardinalCellIndex( i, j, k );
465 int c = Kokkos::atomic_fetch_add( &counts( cell_id ), 1 );
466 permutes( offsets( cell_id ) + c ) = p;
468 Kokkos::parallel_for(
"Cabana::LinkedCellList::build::create_permute",
469 particle_range, create_permute );
493 template <
class PositionType>
494 void build( PositionType positions,
const std::size_t begin,
495 const std::size_t end )
508 template <
class PositionType>
509 void build( PositionType positions )
511 build( positions, 0,
size( positions ) );
519 Kokkos::parallel_for(
520 "Cabana::LinkedCellList::storeBinIndices",
521 Kokkos::RangePolicy<execution_space>( 0,
totalBins() ), *
this );
533 KOKKOS_INLINE_FUNCTION
536 assert( particle_index >=
static_cast<int>( _begin ) );
537 assert( particle_index <
static_cast<int>( _end ) );
538 return _particle_bins( particle_index - _begin );
548 ijkBinIndex( i, bin_ijk[0], bin_ijk[1], bin_ijk[2] );
549 auto offset =
binOffset( bin_ijk[0], bin_ijk[1], bin_ijk[2] );
550 auto size =
binSize( bin_ijk[0], bin_ijk[1], bin_ijk[2] );
551 for (
size_t p = offset; p < offset +
size; ++p )
555 _particle_bins( p ) = i;
573 KOKKOS_INLINE_FUNCTION
579 KOKKOS_INLINE_FUNCTION
581 int& jmax,
int& kmin,
int& kmax )
const
583 _cell_stencil.getCells( cell, imin, imax, jmin, jmax, kmin, kmax );
590 KOKKOS_INLINE_FUNCTION
607 Impl::CartesianGrid<Scalar> _grid;
619 void allocate(
const int ncell,
const int nparticles )
622 Kokkos::view_alloc( Kokkos::WithoutInitializing,
"counts" ),
625 Kokkos::view_alloc( Kokkos::WithoutInitializing,
"offsets" ),
628 Kokkos::view_alloc( Kokkos::WithoutInitializing,
"permutes" ),
633 Kokkos::view_alloc( Kokkos::WithoutInitializing,
"counts" ),
642template <
class MemorySpace,
class PositionType,
class Scalar>
644 const Scalar grid_min[3],
const Scalar grid_max[3] )
654template <
class MemorySpace,
class PositionType,
class Scalar>
656 const std::size_t end,
const Scalar grid_delta[3],
657 const Scalar grid_min[3],
const Scalar grid_max[3] )
660 positions, begin, end, grid_delta, grid_min, grid_max );
668template <
class MemorySpace,
class PositionType,
class Scalar>
670 const Scalar grid_min[3],
const Scalar grid_max[3],
671 const Scalar neighborhood_radius,
672 const Scalar cell_size_ratio = 1.0 )
675 grid_max, neighborhood_radius,
684template <
class MemorySpace,
class PositionType,
class Scalar>
686 const std::size_t end,
const Scalar grid_delta[3],
687 const Scalar grid_min[3],
const Scalar grid_max[3],
688 const Scalar neighborhood_radius,
689 const Scalar cell_size_ratio = 1.0 )
692 positions, begin, end, grid_delta, grid_min, grid_max,
693 neighborhood_radius, cell_size_ratio );
699struct is_linked_cell_list_impl :
public std::false_type
703template <
typename MemorySpace,
typename Scalar>
704struct is_linked_cell_list_impl<
LinkedCellList<MemorySpace, Scalar>>
705 :
public std::true_type
713 :
public is_linked_cell_list_impl<typename std::remove_cv<T>::type>::type
729template <
class LinkedCellListType,
class PositionType>
731 LinkedCellListType& linked_cell_list, PositionType& positions,
735 Kokkos::is_view<PositionType>::value ) ),
738 permute( linked_cell_list.binningData(), positions );
741 linked_cell_list.update(
true );
743 linked_cell_list.storeParticleBins();
748template <
class MemorySpace,
typename Scalar>
758 KOKKOS_INLINE_FUNCTION
static std::size_t
761 std::size_t total_n = 0;
770 KOKKOS_INLINE_FUNCTION
773 std::size_t max_n = 0;
783 KOKKOS_INLINE_FUNCTION
static std::size_t
787 int imin, imax, jmin, jmax, kmin, kmax;
789 jmin, jmax, kmin, kmax );
792 for (
int i = imin; i < imax; ++i )
793 for (
int j = jmin; j < jmax; ++j )
794 for (
int k = kmin; k < kmax; ++k )
796 total_count += list.
binSize( i, j, k );
803 KOKKOS_INLINE_FUNCTION
static std::size_t
805 const std::size_t neighbor_index )
807 std::size_t total_count = 0;
808 std::size_t previous_count = 0;
809 int imin, imax, jmin, jmax, kmin, kmax;
811 jmin, jmax, kmin, kmax );
814 for (
int i = imin; i < imax; ++i )
815 for (
int j = jmin; j < jmax; ++j )
816 for (
int k = kmin; k < kmax; ++k )
818 total_count += list.
binSize( i, j, k );
820 if ( total_count > neighbor_index )
822 int particle_id = list.
binOffset( i, j, k ) +
823 ( neighbor_index - previous_count );
826 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:109
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:165
KOKKOS_INLINE_FUNCTION std::size_t getParticleBegin() const
Beginning of binned range.
Definition Cabana_LinkedCellList.hpp:264
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:395
void build(PositionType positions)
Build the linked cell list with all particles.
Definition Cabana_LinkedCellList.hpp:509
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:197
KOKKOS_INLINE_FUNCTION auto getParticleBin(const int particle_index) const
Get the bin cell index of the input particle.
Definition Cabana_LinkedCellList.hpp:534
LinkedCellList()=default
Default constructor.
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:325
Kokkos::View< int *, memory_space > CountView
Binning view type.
Definition Cabana_LinkedCellList.hpp:107
KOKKOS_INLINE_FUNCTION int numParticles() const
Number of binned particles.
Definition Cabana_LinkedCellList.hpp:260
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:296
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:580
KOKKOS_INLINE_FUNCTION stencil_type cellStencil() const
Get the linked cell stencil.
Definition Cabana_LinkedCellList.hpp:372
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:338
Cabana::LinkedCellStencil< Scalar > stencil_type
Stencil type.
Definition Cabana_LinkedCellList.hpp:111
MemorySpace memory_space
Kokkos memory space.
Definition Cabana_LinkedCellList.hpp:98
KOKKOS_INLINE_FUNCTION auto getParticle(const int offset) const
Get a candidate neighbor particle at a given binned offset.
Definition Cabana_LinkedCellList.hpp:591
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:350
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:129
typename memory_space::size_type size_type
Memory space size type.
Definition Cabana_LinkedCellList.hpp:104
KOKKOS_INLINE_FUNCTION std::size_t getParticleEnd() const
End of binned range.
Definition Cabana_LinkedCellList.hpp:268
KOKKOS_INLINE_FUNCTION auto sorted() const
Definition Cabana_LinkedCellList.hpp:574
auto getParticleBins() const
Get the bin cell index for each binned particle.
Definition Cabana_LinkedCellList.hpp:528
KOKKOS_INLINE_FUNCTION int totalBins() const
Get the total number of bins.
Definition Cabana_LinkedCellList.hpp:275
void update(const bool sorted)
Definition Cabana_LinkedCellList.hpp:568
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:312
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:494
KOKKOS_FUNCTION void operator()(const int i) const
Determines which particles belong to bin i.
Definition Cabana_LinkedCellList.hpp:545
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:237
typename memory_space::execution_space execution_space
Default execution space.
Definition Cabana_LinkedCellList.hpp:102
BinningData< MemorySpace > binningData() const
Get the 1d bin data.
Definition Cabana_LinkedCellList.hpp:378
KOKKOS_INLINE_FUNCTION std::size_t rangeBegin() const
The beginning particle index binned by the linked cell list.
Definition Cabana_LinkedCellList.hpp:359
void storeParticleBins()
Store the bin cell index for each binned particle.
Definition Cabana_LinkedCellList.hpp:517
KOKKOS_INLINE_FUNCTION std::size_t rangeEnd() const
The ending particle index binned by the linked cell list.
Definition Cabana_LinkedCellList.hpp:365
KOKKOS_INLINE_FUNCTION int numBin(const int dim) const
Get the number of bins in a given dimension.
Definition Cabana_LinkedCellList.hpp:283
MemorySpace memory_space
Kokkos memory space.
Definition Cabana_LinkedCellList.hpp:753
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:784
LinkedCellList< MemorySpace, Scalar > list_type
Neighbor list type.
Definition Cabana_LinkedCellList.hpp:755
static KOKKOS_INLINE_FUNCTION std::size_t maxNeighbor(const list_type &list)
Get the maximum number of neighbors per particles.
Definition Cabana_LinkedCellList.hpp:771
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:804
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:759
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:1019
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:730
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:643
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
Default Constructor.
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:714
Slice static type checker.
Definition Cabana_Slice.hpp:868