16#ifndef CABANA_VERLETLIST_HPP
17#define CABANA_VERLETLIST_HPP
23#include <Kokkos_Core.hpp>
24#include <Kokkos_Profiling_ScopedRegion.hpp>
46template <
class MemorySpace,
class LayoutTag>
50template <
class MemorySpace>
57 Kokkos::View<int*, memory_space>
counts;
66 KOKKOS_INLINE_FUNCTION
70 Kokkos::atomic_fetch_add( &
counts( pid ), 1 ) ) = nid;
74 KOKKOS_INLINE_FUNCTION
75 void setNeighbor(
const int pid,
const int nid,
const int new_id )
const
82template <
class MemorySpace>
89 Kokkos::View<int*, memory_space>
counts;
99 KOKKOS_INLINE_FUNCTION
102 std::size_t count = Kokkos::atomic_fetch_add( &
counts( pid ), 1 );
108 KOKKOS_INLINE_FUNCTION
109 void setNeighbor(
const int pid,
const int nid,
const int new_id )
const
126template <
class DeviceType,
class RandomAccessPositionType,
class RadiusType,
127 class AlgorithmTag,
class LayoutTag,
class BuildOpTag>
128struct VerletListBuilder
131 using device = DeviceType;
132 using PositionValueType =
typename RandomAccessPositionType::value_type;
133 using memory_space =
typename device::memory_space;
134 using execution_space =
typename device::execution_space;
137 VerletListData<memory_space, LayoutTag> _data;
139 PositionValueType rsqr;
144 RandomAccessPositionType _position;
145 std::size_t pid_begin, pid_end;
148 BinningData<memory_space> bin_data_1d;
149 LinkedCellList<memory_space, PositionValueType> linked_cell_list;
159 template <
class PositionType>
160 VerletListBuilder( PositionType positions,
const std::size_t begin,
161 const std::size_t end,
162 const RadiusType neighborhood_radius,
163 const PositionValueType cell_size_ratio,
164 const PositionValueType grid_min[3],
165 const PositionValueType grid_max[3],
166 const std::size_t max_neigh )
169 , alloc_n( max_neigh )
171 init( positions, neighborhood_radius, cell_size_ratio, grid_min,
175 radius = neighborhood_radius;
180 template <
class PositionType>
181 VerletListBuilder( PositionType positions,
const std::size_t begin,
182 const std::size_t end,
183 const PositionValueType background_radius,
184 const RadiusType neighborhood_radius,
185 const PositionValueType cell_size_ratio,
186 const PositionValueType grid_min[3],
187 const PositionValueType grid_max[3],
188 const std::size_t max_neigh )
191 , alloc_n( max_neigh )
193 assert( positions.size() == neighborhood_radius.size() );
194 init( positions, background_radius, cell_size_ratio, grid_min,
200 radius = neighborhood_radius;
203 template <
class PositionType>
204 void init( PositionType positions,
205 const PositionValueType neighborhood_radius,
206 const PositionValueType cell_size_ratio,
207 const PositionValueType grid_min[3],
208 const PositionValueType grid_max[3] )
214 _data.counts = Kokkos::View<int*, memory_space>(
"num_neighbors",
218 initCounts( LayoutTag() );
221 _position = positions;
227 double grid_size = cell_size_ratio * neighborhood_radius;
228 PositionValueType grid_delta[3] = { grid_size, grid_size, grid_size };
229 linked_cell_list = createLinkedCellList<memory_space>(
230 _position, grid_delta, grid_min, grid_max, neighborhood_radius,
232 bin_data_1d = linked_cell_list.binningData();
235 rsqr = neighborhood_radius * neighborhood_radius;
240 KOKKOS_INLINE_FUNCTION
auto withinCutoff( [[maybe_unused]]
const int i,
241 const double dist_sqr )
const
245 if constexpr ( is_slice<RadiusType>::value ||
246 Kokkos::is_view<RadiusType>::value )
247 return dist_sqr <= radius( i ) * radius( i );
250 return dist_sqr <= rsqr;
255 KOKKOS_INLINE_FUNCTION
auto
256 neighborNotWithinCutoff( [[maybe_unused]]
const int j,
257 [[maybe_unused]]
const double dist_sqr )
const
260 if constexpr ( is_slice<RadiusType>::value ||
261 Kokkos::is_view<RadiusType>::value )
263 return dist_sqr >= radius( j ) * radius( j );
273 KOKKOS_INLINE_FUNCTION
auto countNeighbor(
const int i,
const int j,
274 const double dist_sqr )
const
278 if ( withinCutoff( i, dist_sqr ) )
282 if ( neighborNotWithinCutoff( j, dist_sqr ) )
289 KOKKOS_INLINE_FUNCTION
void addNeighbor(
const int i,
const int j,
290 const double dist_sqr )
const
293 if ( withinCutoff( i, dist_sqr ) )
295 _data.addNeighbor( i, j );
298 if ( neighborNotWithinCutoff( j, dist_sqr ) )
299 _data.addNeighbor( j, i );
304 struct CountNeighborsTag
307 using CountNeighborsPolicy =
308 Kokkos::TeamPolicy<execution_space, CountNeighborsTag,
309 Kokkos::IndexType<int>,
310 Kokkos::Schedule<Kokkos::Dynamic>>;
312 KOKKOS_INLINE_FUNCTION
314 operator()(
const CountNeighborsTag&,
315 const typename CountNeighborsPolicy::member_type& team )
const
319 int cell = team.league_rank();
322 int imin, imax, jmin, jmax, kmin, kmax;
323 linked_cell_list.getStencilCells( cell, imin, imax, jmin, jmax, kmin,
327 std::size_t b_offset = bin_data_1d.binOffset( cell );
328 Kokkos::parallel_for(
329 Kokkos::TeamThreadRange( team, 0, bin_data_1d.binSize( cell ) ),
334 std::size_t pid = linked_cell_list.permutation( bi + b_offset );
336 if ( ( pid >= pid_begin ) && ( pid < pid_end ) )
339 double x_p = _position( pid, 0 );
340 double y_p = _position( pid, 1 );
341 double z_p = _position( pid, 2 );
344 int stencil_count = 0;
345 for ( int i = imin; i < imax; ++i )
346 for ( int j = jmin; j < jmax; ++j )
347 for ( int k = kmin; k < kmax; ++k )
353 linked_cell_list.cellStencil()
354 .grid.minDistanceToPoint(
355 x_p, y_p, z_p, i, j, k ) ) )
357 std::size_t n_offset =
358 linked_cell_list.binOffset( i, j, k );
360 linked_cell_list.binSize( i, j, k );
366 neighbor_reduce( team, pid, x_p, y_p, z_p,
368 cell_count, BuildOpTag() );
369 stencil_count += cell_count;
372 Kokkos::single( Kokkos::PerThread( team ), [&]()
373 { _data.counts( pid ) = stencil_count; } );
379 KOKKOS_INLINE_FUNCTION
void
380 neighbor_reduce(
const typename CountNeighborsPolicy::member_type& team,
381 const std::size_t pid,
const double x_p,
const double y_p,
382 const double z_p,
const int n_offset,
const int num_n,
383 int& cell_count, TeamVectorOpTag )
const
385 Kokkos::parallel_reduce(
386 Kokkos::ThreadVectorRange( team, num_n ),
387 [&](
const int n,
int& local_count ) {
388 neighbor_kernel( pid, x_p, y_p, z_p, n_offset, n, local_count );
394 KOKKOS_INLINE_FUNCTION
395 void neighbor_reduce(
const typename CountNeighborsPolicy::member_type,
396 const std::size_t pid,
const double x_p,
397 const double y_p,
const double z_p,
398 const int n_offset,
const int num_n,
int& cell_count,
401 for (
int n = 0; n < num_n; n++ )
402 neighbor_kernel( pid, x_p, y_p, z_p, n_offset, n, cell_count );
406 KOKKOS_INLINE_FUNCTION
407 void neighbor_kernel(
const int pid,
const double x_p,
const double y_p,
408 const double z_p,
const int n_offset,
const int n,
409 int& local_count )
const
412 std::size_t nid = linked_cell_list.permutation( n_offset + n );
415 double x_n = _position( nid, 0 );
416 double y_n = _position( nid, 1 );
417 double z_n = _position( nid, 2 );
420 if ( NeighborDiscriminator<AlgorithmTag>::isValid(
421 pid, x_p, y_p, z_p, nid, x_n, y_n, z_n ) )
425 PositionValueType dx = x_p - x_n;
426 PositionValueType dy = y_p - y_n;
427 PositionValueType dz = z_p - z_n;
428 PositionValueType dist_sqr = dx * dx + dy * dy + dz * dz;
431 local_count += countNeighbor( pid, nid, dist_sqr );
437 template <
class KokkosMemorySpace>
440 using kokkos_mem_space = KokkosMemorySpace;
441 Kokkos::View<int*, kokkos_mem_space> counts;
442 Kokkos::View<int*, kokkos_mem_space> offsets;
443 KOKKOS_INLINE_FUNCTION
444 void operator()(
const int i,
int& update,
const bool final_pass )
const
452 void initCounts( VerletLayoutCSR ) {}
454 void initCounts( VerletLayout2D )
460 _data.neighbors = Kokkos::View<int**, memory_space>(
461 Kokkos::ViewAllocateWithoutInitializing(
"neighbors" ),
462 _data.counts.size(), alloc_n );
466 void processCounts( VerletLayoutCSR )
469 _data.offsets = Kokkos::View<int*, memory_space>(
470 Kokkos::ViewAllocateWithoutInitializing(
"neighbor_offsets" ),
471 _data.counts.size() );
474 OffsetScanOp<memory_space> offset_op;
475 offset_op.counts = _data.counts;
476 offset_op.offsets = _data.offsets;
477 int total_num_neighbor;
478 Kokkos::RangePolicy<execution_space> range_policy(
479 0, _data.counts.extent( 0 ) );
480 Kokkos::parallel_scan(
"Cabana::VerletListBuilder::offset_scan",
481 range_policy, offset_op, total_num_neighbor );
485 _data.neighbors = Kokkos::View<int*, memory_space>(
486 Kokkos::ViewAllocateWithoutInitializing(
"neighbors" ),
487 total_num_neighbor );
490 Kokkos::deep_copy( _data.counts, 0 );
495 void processCounts( VerletLayout2D )
498 auto counts = _data.counts;
500 Kokkos::Max<int> max_reduce( max );
501 Kokkos::parallel_reduce(
502 "Cabana::VerletListBuilder::reduce_max",
503 Kokkos::RangePolicy<execution_space>( 0, _data.counts.size() ),
504 KOKKOS_LAMBDA(
const int i,
int& value ) {
505 if ( counts( i ) > value )
510 _data.max_n =
static_cast<std::size_t
>( max );
513 if ( count or _data.max_n > _data.neighbors.extent( 1 ) )
516 Kokkos::deep_copy( _data.counts, 0 );
517 _data.neighbors = Kokkos::View<int**, memory_space>(
518 Kokkos::ViewAllocateWithoutInitializing(
"neighbors" ),
519 _data.counts.size(), _data.max_n );
524 struct FillNeighborsTag
527 using FillNeighborsPolicy =
528 Kokkos::TeamPolicy<execution_space, FillNeighborsTag,
529 Kokkos::IndexType<int>,
530 Kokkos::Schedule<Kokkos::Dynamic>>;
531 KOKKOS_INLINE_FUNCTION
533 operator()(
const FillNeighborsTag&,
534 const typename FillNeighborsPolicy::member_type& team )
const
538 int cell = team.league_rank();
541 int imin, imax, jmin, jmax, kmin, kmax;
542 linked_cell_list.getStencilCells( cell, imin, imax, jmin, jmax, kmin,
546 std::size_t b_offset = bin_data_1d.binOffset( cell );
547 Kokkos::parallel_for(
548 Kokkos::TeamThreadRange( team, 0, bin_data_1d.binSize( cell ) ),
553 std::size_t pid = linked_cell_list.permutation( bi + b_offset );
555 if ( ( pid >= pid_begin ) && ( pid < pid_end ) )
558 double x_p = _position( pid, 0 );
559 double y_p = _position( pid, 1 );
560 double z_p = _position( pid, 2 );
563 for ( int i = imin; i < imax; ++i )
564 for ( int j = jmin; j < jmax; ++j )
565 for ( int k = kmin; k < kmax; ++k )
571 linked_cell_list.cellStencil()
572 .grid.minDistanceToPoint(
573 x_p, y_p, z_p, i, j, k ) ) )
577 std::size_t n_offset =
578 linked_cell_list.binOffset( i, j, k );
580 linked_cell_list.binSize( i, j, k );
581 neighbor_for( team, pid, x_p, y_p, z_p,
591 KOKKOS_INLINE_FUNCTION
void
592 neighbor_for(
const typename FillNeighborsPolicy::member_type& team,
593 const std::size_t pid,
const double x_p,
const double y_p,
594 const double z_p,
const int n_offset,
const int num_n,
597 Kokkos::parallel_for(
598 Kokkos::ThreadVectorRange( team, num_n ), [&](
const int n )
599 { neighbor_kernel( pid, x_p, y_p, z_p, n_offset, n ); } );
603 KOKKOS_INLINE_FUNCTION
604 void neighbor_for(
const typename FillNeighborsPolicy::member_type team,
605 const std::size_t pid,
const double x_p,
606 const double y_p,
const double z_p,
const int n_offset,
609 for (
int n = 0; n < num_n; n++ )
611 Kokkos::PerThread( team ),
612 [&]() { neighbor_kernel( pid, x_p, y_p, z_p, n_offset, n ); } );
616 KOKKOS_INLINE_FUNCTION
617 void neighbor_kernel(
const int pid,
const double x_p,
const double y_p,
618 const double z_p,
const int n_offset,
622 std::size_t nid = linked_cell_list.permutation( n_offset + n );
625 double x_n = _position( nid, 0 );
626 double y_n = _position( nid, 1 );
627 double z_n = _position( nid, 2 );
631 pid, x_p, y_p, z_p, nid, x_n, y_n, z_n ) )
635 PositionValueType dx = x_p - x_n;
636 PositionValueType dy = y_p - y_n;
637 PositionValueType dz = z_p - z_n;
638 PositionValueType dist_sqr = dx * dx + dy * dy + dz * dz;
642 addNeighbor( pid, nid, dist_sqr );
649template <
class DeviceType,
class AlgorithmTag,
class LayoutTag,
650 class BuildOpTag,
class PositionType>
651auto createVerletListBuilder(
652 PositionType x,
const std::size_t begin,
const std::size_t end,
653 const typename PositionType::value_type radius,
654 const typename PositionType::value_type cell_size_ratio,
655 const typename PositionType::value_type grid_min[3],
656 const typename PositionType::value_type grid_max[3],
657 const std::size_t max_neigh,
658 typename std::enable_if<( is_slice<PositionType>::value ),
int>::type* = 0 )
660 using RandomAccessPositionType =
typename PositionType::random_access_slice;
661 return VerletListBuilder<DeviceType, RandomAccessPositionType,
662 typename PositionType::value_type, AlgorithmTag,
663 LayoutTag, BuildOpTag>(
664 x, begin, end, radius, cell_size_ratio, grid_min, grid_max, max_neigh );
667template <
class DeviceType,
class AlgorithmTag,
class LayoutTag,
668 class BuildOpTag,
class PositionType>
669auto createVerletListBuilder(
670 PositionType x,
const std::size_t begin,
const std::size_t end,
671 const typename PositionType::value_type radius,
672 const typename PositionType::value_type cell_size_ratio,
673 const typename PositionType::value_type grid_min[3],
674 const typename PositionType::value_type grid_max[3],
675 const std::size_t max_neigh,
676 typename std::enable_if<( Kokkos::is_view<PositionType>::value ),
679 using RandomAccessPositionType =
680 Kokkos::View<
typename PositionType::value_type**, DeviceType,
681 Kokkos::MemoryTraits<Kokkos::RandomAccess>>;
682 return VerletListBuilder<DeviceType, RandomAccessPositionType,
683 typename PositionType::value_type, AlgorithmTag,
684 LayoutTag, BuildOpTag>(
685 x, begin, end, radius, cell_size_ratio, grid_min, grid_max, max_neigh );
688template <
class DeviceType,
class AlgorithmTag,
class LayoutTag,
689 class BuildOpTag,
class PositionType,
class RadiusType>
690auto createVerletListBuilder(
691 PositionType x,
const std::size_t begin,
const std::size_t end,
692 const typename PositionType::value_type background_radius,
693 const RadiusType radius,
694 const typename PositionType::value_type cell_size_ratio,
695 const typename PositionType::value_type grid_min[3],
696 const typename PositionType::value_type grid_max[3],
697 const std::size_t max_neigh,
698 typename std::enable_if<( is_slice<PositionType>::value ),
int>::type* = 0 )
700 using RandomAccessPositionType =
typename PositionType::random_access_slice;
701 return VerletListBuilder<DeviceType, RandomAccessPositionType, RadiusType,
702 AlgorithmTag, LayoutTag, BuildOpTag>(
703 x, begin, end, background_radius, radius, cell_size_ratio, grid_min,
704 grid_max, max_neigh );
707template <
class DeviceType,
class AlgorithmTag,
class LayoutTag,
708 class BuildOpTag,
class PositionType,
class RadiusType>
709auto createVerletListBuilder(
710 PositionType x,
const std::size_t begin,
const std::size_t end,
711 const typename PositionType::value_type background_radius,
712 const RadiusType radius,
713 const typename PositionType::value_type cell_size_ratio,
714 const typename PositionType::value_type grid_min[3],
715 const typename PositionType::value_type grid_max[3],
716 const std::size_t max_neigh,
717 typename std::enable_if<( Kokkos::is_view<PositionType>::value ),
720 using RandomAccessPositionType =
721 Kokkos::View<
typename PositionType::value_type**, DeviceType,
722 Kokkos::MemoryTraits<Kokkos::RandomAccess>>;
723 return VerletListBuilder<DeviceType, RandomAccessPositionType, RadiusType,
724 AlgorithmTag, LayoutTag, BuildOpTag>(
725 x, begin, end, background_radius, radius, cell_size_ratio, grid_min,
726 grid_max, max_neigh );
752template <
class MemorySpace,
class AlgorithmTag,
class LayoutTag,
753 class BuildTag = TeamVectorOpTag>
757 static_assert( Kokkos::is_memory_space<MemorySpace>::value,
"" );
807 template <
class PositionType>
809 PositionType x,
const std::size_t begin,
const std::size_t end,
810 const typename PositionType::value_type neighborhood_radius,
811 const typename PositionType::value_type cell_size_ratio,
812 const typename PositionType::value_type grid_min[3],
813 const typename PositionType::value_type grid_max[3],
814 const std::size_t max_neigh = 0,
816 Kokkos::is_view<PositionType>::value ),
819 build( x, begin, end, neighborhood_radius, cell_size_ratio, grid_min,
820 grid_max, max_neigh );
859 template <
class PositionSlice,
class RadiusSlice>
860 VerletList( PositionSlice x,
const std::size_t begin,
const std::size_t end,
861 const typename PositionSlice::value_type background_radius,
862 RadiusSlice neighborhood_radius,
863 const typename PositionSlice::value_type cell_size_ratio,
864 const typename PositionSlice::value_type grid_min[3],
865 const typename PositionSlice::value_type grid_max[3],
866 const std::size_t max_neigh = 0,
870 build( x, begin, end, background_radius, neighborhood_radius,
871 cell_size_ratio, grid_min, grid_max, max_neigh );
878 template <
class PositionType>
880 build( PositionType x,
const std::size_t begin,
const std::size_t end,
881 const typename PositionType::value_type neighborhood_radius,
882 const typename PositionType::value_type cell_size_ratio,
883 const typename PositionType::value_type grid_min[3],
884 const typename PositionType::value_type grid_max[3],
885 const std::size_t max_neigh = 0,
887 Kokkos::is_view<PositionType>::value ),
892 cell_size_ratio, grid_min, grid_max, max_neigh );
898 template <
class PositionType,
class ExecutionSpace>
900 build( ExecutionSpace, PositionType x,
const std::size_t begin,
901 const std::size_t end,
902 const typename PositionType::value_type neighborhood_radius,
903 const typename PositionType::value_type cell_size_ratio,
904 const typename PositionType::value_type grid_min[3],
905 const typename PositionType::value_type grid_max[3],
906 const std::size_t max_neigh = 0,
908 Kokkos::is_view<PositionType>::value ),
911 Kokkos::Profiling::ScopedRegion region(
"Cabana::VerletList::build" );
915 assert( end >= begin );
916 assert( end <=
size( x ) );
918 using device_type = Kokkos::Device<ExecutionSpace, memory_space>;
920 auto builder = Impl::createVerletListBuilder<device_type, AlgorithmTag,
921 LayoutTag, BuildTag>(
922 x, begin, end, neighborhood_radius, cell_size_ratio, grid_min,
923 grid_max, max_neigh );
924 buildImpl( builder );
931 template <
class PositionSlice,
class RadiusSlice>
932 void build( PositionSlice x,
const std::size_t begin,
const std::size_t end,
933 const typename PositionSlice::value_type background_radius,
934 RadiusSlice neighborhood_radius,
935 const typename PositionSlice::value_type cell_size_ratio,
936 const typename PositionSlice::value_type grid_min[3],
937 const typename PositionSlice::value_type grid_max[3],
938 const std::size_t max_neigh = 0 )
942 neighborhood_radius, cell_size_ratio, grid_min, grid_max,
949 template <
class PositionSlice,
class RadiusSlice,
class ExecutionSpace>
950 void build( ExecutionSpace, PositionSlice x,
const std::size_t begin,
951 const std::size_t end,
952 const typename PositionSlice::value_type background_radius,
953 RadiusSlice neighborhood_radius,
954 const typename PositionSlice::value_type cell_size_ratio,
955 const typename PositionSlice::value_type grid_min[3],
956 const typename PositionSlice::value_type grid_max[3],
957 const std::size_t max_neigh = 0 )
959 Kokkos::Profiling::ScopedRegion region(
"Cabana::VerletList::build" );
963 assert( end >= begin );
964 assert( end <= x.size() );
967 using device_type = Kokkos::Device<ExecutionSpace, memory_space>;
968 auto builder = Impl::createVerletListBuilder<device_type, AlgorithmTag,
969 LayoutTag, BuildTag>(
970 x, begin, end, background_radius, neighborhood_radius,
971 cell_size_ratio, grid_min, grid_max, max_neigh );
972 buildImpl( builder );
976 template <
class BuilderType>
977 void buildImpl( BuilderType builder )
987 typename BuilderType::FillNeighborsPolicy fill_policy(
988 builder.bin_data_1d.numBin(), Kokkos::AUTO, 4 );
991 typename BuilderType::CountNeighborsPolicy count_policy(
992 builder.bin_data_1d.numBin(), Kokkos::AUTO, 4 );
993 Kokkos::parallel_for(
"Cabana::VerletList::count_neighbors",
994 count_policy, builder );
998 builder.processCounts( LayoutTag() );
999 Kokkos::parallel_for(
"Cabana::VerletList::fill_neighbors",
1000 fill_policy, builder );
1006 builder.processCounts( LayoutTag() );
1010 if ( builder.count or builder.refill )
1012 Kokkos::parallel_for(
"Cabana::VerletList::fill_neighbors",
1013 fill_policy, builder );
1018 _data = builder._data;
1023 KOKKOS_INLINE_FUNCTION
1025 const std::size_t neighbor_index,
1026 const int new_index )
const
1028 _data.setNeighbor( particle_index, neighbor_index, new_index );
1036template <
class MemorySpace,
class AlgorithmTag,
class BuildTag>
1048 KOKKOS_INLINE_FUNCTION
1052 return list.
_data.neighbors.extent( 0 );
1056 KOKKOS_INLINE_FUNCTION
1059 std::size_t num_p = list.
_data.counts.size();
1064 KOKKOS_INLINE_FUNCTION
1066 const std::size_t particle_index )
1068 return list.
_data.counts( particle_index );
1073 KOKKOS_INLINE_FUNCTION
1075 const std::size_t particle_index,
1076 const std::size_t neighbor_index )
1078 return list.
_data.neighbors( list.
_data.offsets( particle_index ) +
1085template <
class MemorySpace,
class AlgorithmTag,
class BuildTag>
1097 KOKKOS_INLINE_FUNCTION
1100 std::size_t num_p = list.
_data.counts.size();
1105 KOKKOS_INLINE_FUNCTION
1109 return list.
_data.max_n;
1113 KOKKOS_INLINE_FUNCTION
1115 const std::size_t particle_index )
1117 return list.
_data.counts( particle_index );
1122 KOKKOS_INLINE_FUNCTION
1124 const std::size_t particle_index,
1125 const std::size_t neighbor_index )
1127 return list.
_data.neighbors( particle_index, neighbor_index );
std::enable_if_t< 3==Array_t::num_space_dim, void > update(Array_t &a, const typename Array_t::value_type alpha, const Array_t &b, const typename Array_t::value_type beta, DecompositionTag tag)
Update two vectors such that a = alpha * a + beta * b. 3D specialization.
Definition Cabana_Grid_Array.hpp:617
KOKKOS_INLINE_FUNCTION std::enable_if_t< 3==SplineDataType::num_space_dim, void > value(const ViewType &view, const SplineDataType &sd, PointDataType &result, typename std::enable_if<(std::rank< PointDataType >::value==0), void * >::type=0)
Interpolate a scalar value to a point. 3D specialization.
Definition Cabana_Grid_Interpolation.hpp:56
Linked cell list binning (spatial sorting) and neighbor iteration.
KOKKOS_INLINE_FUNCTION std::size_t maxNeighbor(const ListType &list, const std::size_t num_particles)
Iterate to find the maximum number of neighbors.
Definition Cabana_NeighborList.hpp:164
KOKKOS_INLINE_FUNCTION std::size_t totalNeighbor(const ListType &list, const std::size_t num_particles)
Iterate to get the total number of neighbors.
Definition Cabana_NeighborList.hpp:152
SIMD and neighbor extension of Kokkos parallel iteration.
Neighborhood discriminator.
Definition Cabana_NeighborList.hpp:55
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_VerletList.hpp:1123
VerletList< MemorySpace, AlgorithmTag, VerletLayout2D, BuildTag > list_type
Neighbor list type.
Definition Cabana_VerletList.hpp:1093
MemorySpace memory_space
Kokkos memory space.
Definition Cabana_VerletList.hpp:1091
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_VerletList.hpp:1114
static KOKKOS_INLINE_FUNCTION std::size_t totalNeighbor(const list_type &list)
Get the total number of neighbors across all particles.
Definition Cabana_VerletList.hpp:1098
static KOKKOS_INLINE_FUNCTION std::size_t maxNeighbor(const list_type &list)
Get the maximum number of neighbors per particle.
Definition Cabana_VerletList.hpp:1106
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_VerletList.hpp:1065
VerletList< MemorySpace, AlgorithmTag, VerletLayoutCSR, BuildTag > list_type
Neighbor list type.
Definition Cabana_VerletList.hpp:1044
static KOKKOS_INLINE_FUNCTION std::size_t maxNeighbor(const list_type &list)
Get the maximum number of neighbors across all particles.
Definition Cabana_VerletList.hpp:1057
static KOKKOS_INLINE_FUNCTION std::size_t totalNeighbor(const list_type &list)
Get the total number of neighbors across all particles.
Definition Cabana_VerletList.hpp:1049
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_VerletList.hpp:1074
MemorySpace memory_space
Kokkos memory space.
Definition Cabana_VerletList.hpp:1042
Neighbor list interface. Provides an interface callable at the functor level that gives access to nei...
Definition Cabana_NeighborList.hpp:114
Neighbor operations are executed with team parallelism.
Definition Cabana_Parallel.hpp:206
Neighbor operations are executed with team vector parallelism.
Definition Cabana_Parallel.hpp:211
Neighbor list implementation based on binning particles on a 3d Cartesian grid with cells of the same...
Definition Cabana_VerletList.hpp:755
void build(PositionSlice x, const std::size_t begin, const std::size_t end, const typename PositionSlice::value_type background_radius, RadiusSlice neighborhood_radius, const typename PositionSlice::value_type cell_size_ratio, const typename PositionSlice::value_type grid_min[3], const typename PositionSlice::value_type grid_max[3], const std::size_t max_neigh=0)
Given a list of particle positions and a neighborhood radius calculate the neighbor list.
Definition Cabana_VerletList.hpp:932
VerletListData< memory_space, VerletLayoutCSR > _data
Definition Cabana_VerletList.hpp:766
VerletList(PositionType x, const std::size_t begin, const std::size_t end, const typename PositionType::value_type neighborhood_radius, const typename PositionType::value_type cell_size_ratio, const typename PositionType::value_type grid_min[3], const typename PositionType::value_type grid_max[3], const std::size_t max_neigh=0, typename std::enable_if<(is_slice< PositionType >::value||Kokkos::is_view< PositionType >::value), int >::type *=0)
VerletList constructor. Given a list of particle positions and a neighborhood radius calculate the ne...
Definition Cabana_VerletList.hpp:808
KOKKOS_INLINE_FUNCTION void setNeighbor(const std::size_t particle_index, const std::size_t neighbor_index, const int new_index) const
Modify a neighbor in the list; for example, mark it as a broken bond.
Definition Cabana_VerletList.hpp:1024
VerletList()=default
Default constructor.
typename memory_space::execution_space execution_space
Kokkos default execution space for this memory space.
Definition Cabana_VerletList.hpp:763
void build(ExecutionSpace, PositionType x, const std::size_t begin, const std::size_t end, const typename PositionType::value_type neighborhood_radius, const typename PositionType::value_type cell_size_ratio, const typename PositionType::value_type grid_min[3], const typename PositionType::value_type grid_max[3], const std::size_t max_neigh=0, typename std::enable_if<(is_slice< PositionType >::value||Kokkos::is_view< PositionType >::value), int >::type *=0)
Given a list of particle positions and a neighborhood radius calculate the neighbor list.
Definition Cabana_VerletList.hpp:900
MemorySpace memory_space
Kokkos memory space in which the neighbor list data resides.
Definition Cabana_VerletList.hpp:760
void build(ExecutionSpace, PositionSlice x, const std::size_t begin, const std::size_t end, const typename PositionSlice::value_type background_radius, RadiusSlice neighborhood_radius, const typename PositionSlice::value_type cell_size_ratio, const typename PositionSlice::value_type grid_min[3], const typename PositionSlice::value_type grid_max[3], const std::size_t max_neigh=0)
Given a list of particle positions and a neighborhood radius calculate the neighbor list.
Definition Cabana_VerletList.hpp:950
VerletList(PositionSlice x, const std::size_t begin, const std::size_t end, const typename PositionSlice::value_type background_radius, RadiusSlice neighborhood_radius, const typename PositionSlice::value_type cell_size_ratio, const typename PositionSlice::value_type grid_min[3], const typename PositionSlice::value_type grid_max[3], const std::size_t max_neigh=0, typename std::enable_if<(is_slice< PositionSlice >::value), int >::type *=0)
VerletList constructor. Given a list of particle positions and a neighborhood radius calculate the ne...
Definition Cabana_VerletList.hpp:860
void build(PositionType x, const std::size_t begin, const std::size_t end, const typename PositionType::value_type neighborhood_radius, const typename PositionType::value_type cell_size_ratio, const typename PositionType::value_type grid_min[3], const typename PositionType::value_type grid_max[3], const std::size_t max_neigh=0, typename std::enable_if<(is_slice< PositionType >::value||Kokkos::is_view< PositionType >::value), int >::type *=0)
Definition Cabana_VerletList.hpp:880
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
2D array neighbor list layout.
Definition Cabana_VerletList.hpp:40
CSR (compressed sparse row) neighbor list layout.
Definition Cabana_VerletList.hpp:35
KOKKOS_INLINE_FUNCTION void addNeighbor(const int pid, const int nid) const
Add a neighbor to the list.
Definition Cabana_VerletList.hpp:100
MemorySpace memory_space
Kokkos memory space.
Definition Cabana_VerletList.hpp:86
Kokkos::View< int *, memory_space > counts
Number of neighbors per particle.
Definition Cabana_VerletList.hpp:89
Kokkos::View< int **, memory_space > neighbors
Neighbor list.
Definition Cabana_VerletList.hpp:92
KOKKOS_INLINE_FUNCTION void setNeighbor(const int pid, const int nid, const int new_id) const
Modify a neighbor in the list.
Definition Cabana_VerletList.hpp:109
std::size_t max_n
Definition Cabana_VerletList.hpp:96
KOKKOS_INLINE_FUNCTION void setNeighbor(const int pid, const int nid, const int new_id) const
Modify a neighbor in the list.
Definition Cabana_VerletList.hpp:75
Kokkos::View< int *, memory_space > offsets
Offsets into the neighbor list.
Definition Cabana_VerletList.hpp:60
MemorySpace memory_space
Kokkos memory space.
Definition Cabana_VerletList.hpp:54
Kokkos::View< int *, memory_space > counts
Number of neighbors per particle.
Definition Cabana_VerletList.hpp:57
KOKKOS_INLINE_FUNCTION void addNeighbor(const int pid, const int nid) const
Add a neighbor to the list.
Definition Cabana_VerletList.hpp:67
Kokkos::View< int *, memory_space > neighbors
Neighbor list.
Definition Cabana_VerletList.hpp:63
Definition Cabana_VerletList.hpp:47
Definition Cabana_Types.hpp:88
Slice static type checker.
Definition Cabana_Slice.hpp:861