Cabana 0.8.0-dev
 
Loading...
Searching...
No Matches
Cabana_Experimental_NeighborList.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_EXPERIMENTAL_NEIGHBOR_LIST_HPP
17#define CABANA_EXPERIMENTAL_NEIGHBOR_LIST_HPP
18
20#include <Cabana_Slice.hpp>
21#include <Cabana_Types.hpp> // is_accessible_from
22
23#include <ArborX.hpp>
24
25#include <Kokkos_Core.hpp>
26
27#include <cassert>
28
29namespace Cabana
30{
31namespace Experimental
32{
34namespace stdcxx20
35{
36template <class T>
37struct remove_cvref
38{
39 using type = std::remove_cv_t<std::remove_reference_t<T>>;
40};
41
42template <class T>
43using remove_cvref_t = typename remove_cvref<T>::type;
44} // namespace stdcxx20
45
46namespace Impl
47{
48
49template <typename Positions,
50 typename = std::enable_if_t<Cabana::is_slice<Positions>::value ||
51 Kokkos::is_view_v<Positions>>>
52struct SubPositionsAndRadius
53{
54 using positions_type = Positions;
55 using memory_space = typename Positions::memory_space;
56 Positions data;
57 using size_type = typename Positions::size_type;
58 size_type first;
59 size_type last;
60 using value_type = typename Positions::value_type;
61 value_type radius;
62};
63
64template <typename Positions,
65 typename = std::enable_if_t<
66 Cabana::is_slice<std::remove_reference_t<Positions>>::value ||
67 Kokkos::is_view_v<Positions>>>
68auto makePredicates(
69 Positions&& positions,
70 typename stdcxx20::remove_cvref_t<Positions>::size_type first,
71 typename stdcxx20::remove_cvref_t<Positions>::size_type last,
72 typename stdcxx20::remove_cvref_t<Positions>::value_type radius )
73{
74 return Impl::SubPositionsAndRadius<stdcxx20::remove_cvref_t<Positions>>{
75 std::forward<Positions>( positions ), first, last, radius };
76}
77
78template <typename ExecutionSpace, typename D, typename... P>
79typename Kokkos::View<D, P...>::non_const_value_type
80max_reduce( ExecutionSpace const& space, Kokkos::View<D, P...> const& v )
81{
82 using V = Kokkos::View<D, P...>;
83 static_assert( V::rank == 1 );
84 static_assert( Kokkos::is_execution_space<ExecutionSpace>::value );
85 static_assert(
86 is_accessible_from<typename V::memory_space, ExecutionSpace>::value );
87 using Ret = typename Kokkos::View<D, P...>::non_const_value_type;
88 Ret max_val;
89 Kokkos::parallel_reduce(
90 Kokkos::RangePolicy<ExecutionSpace>( space, 0, v.extent( 0 ) ),
91 KOKKOS_LAMBDA( int i, Ret& partial_max ) {
92 if ( v( i ) > partial_max )
93 {
94 partial_max = v( i );
95 }
96 },
97 Kokkos::Max<Ret>( max_val ) );
98 return max_val;
99}
101} // namespace Impl
102} // namespace Experimental
103} // namespace Cabana
104
105namespace ArborX
106{
108template <typename Positions>
109struct AccessTraits<Positions,
110#if ARBORX_VERSION < 10799
111 PrimitivesTag,
112#endif
113 std::enable_if_t<Cabana::is_slice<Positions>{} ||
114 Kokkos::is_view<Positions>{}>>
115{
117 using memory_space = typename Positions::memory_space;
119 using size_type = typename Positions::size_type;
121 static KOKKOS_FUNCTION size_type size( Positions const& x )
122 {
123 return Cabana::size( x );
124 }
125
126 static KOKKOS_FUNCTION auto get( Positions const& x, size_type i )
127 {
128 return Point{ static_cast<float>( x( i, 0 ) ),
129 static_cast<float>( x( i, 1 ) ),
130 static_cast<float>( x( i, 2 ) ) };
131 }
132};
133
134template <typename Positions>
135struct AccessTraits<Cabana::Experimental::Impl::SubPositionsAndRadius<Positions>
136#if ARBORX_VERSION < 10799
137 ,
138 PredicatesTag
139#endif
140 >
141{
144 Cabana::Experimental::Impl::SubPositionsAndRadius<Positions>;
146 using memory_space = typename PositionLike::memory_space;
148 using size_type = typename PositionLike::size_type;
150 static KOKKOS_FUNCTION size_type size( PositionLike const& x )
151 {
152 return x.last - x.first;
153 }
154
155 static KOKKOS_FUNCTION auto get( PositionLike const& x, size_type i )
156 {
157 assert( i < size( x ) );
158 auto const point = AccessTraits<typename PositionLike::positions_type
159#if ARBORX_VERSION < 10799
160 ,
161 PrimitivesTag
162#endif
163 >::get( x.data, x.first + i );
164 return attach(
165 intersects( Sphere{ point, static_cast<float>( x.radius ) } ),
166 (int)i );
167 }
168};
169} // namespace ArborX
170
171namespace Cabana
172{
173namespace Experimental
174{
175namespace Impl
176{
178
179template <typename Tag>
180struct CollisionFilter;
181
182template <>
183struct CollisionFilter<FullNeighborTag>
184{
185 KOKKOS_FUNCTION bool static keep( int i, int j ) noexcept
186 {
187 return i != j; // discard self-collision
188 }
189};
190
191template <>
192struct CollisionFilter<HalfNeighborTag>
193{
194 KOKKOS_FUNCTION static bool keep( int i, int j ) noexcept { return i > j; }
195};
196
197// Custom callback for ArborX::BVH::query()
198template <typename Tag>
199struct NeighborDiscriminatorCallback
200{
201#if ARBORX_VERSION >= 10799
202 template <typename Predicate, typename Geometry, typename OutputFunctor>
203 KOKKOS_FUNCTION void
204 operator()( Predicate const& predicate,
205 ArborX::PairValueIndex<Geometry, int> const& value_pair,
206 OutputFunctor const& out ) const
207 {
208 int const primitive_index = value_pair.index;
209 int const predicate_index = getData( predicate );
210 if ( CollisionFilter<Tag>::keep( predicate_index, primitive_index ) )
211 {
212 out( primitive_index );
213 }
214 }
215#else
216 template <typename Predicate, typename OutputFunctor>
217 KOKKOS_FUNCTION void operator()( Predicate const& predicate,
218 int primitive_index,
219 OutputFunctor const& out ) const
220 {
221 int const predicate_index = getData( predicate );
222 if ( CollisionFilter<Tag>::keep( predicate_index, primitive_index ) )
223 {
224 out( primitive_index );
225 }
226 }
227#endif
228};
229
230// Count in the first pass
231template <typename Counts, typename Tag>
232struct NeighborDiscriminatorCallback2D_FirstPass
233{
234 Counts counts;
235#if ARBORX_VERSION >= 10799
236 template <typename Predicate, typename Geometry>
237 KOKKOS_FUNCTION void
238 operator()( Predicate const& predicate,
239 ArborX::PairValueIndex<Geometry, int> const& value_pair ) const
240 {
241 int const primitive_index = value_pair.index;
242 int const predicate_index = getData( predicate );
243 if ( CollisionFilter<Tag>::keep( predicate_index, primitive_index ) )
244 {
245 ++counts( predicate_index ); // WARNING see below**
246 }
247 }
248#else
249 template <typename Predicate>
250 KOKKOS_FUNCTION void operator()( Predicate const& predicate,
251 int primitive_index ) const
252 {
253 int const predicate_index = getData( predicate );
254 if ( CollisionFilter<Tag>::keep( predicate_index, primitive_index ) )
255 {
256 ++counts( predicate_index ); // WARNING see below**
257 }
258 }
259#endif
260};
261
262// Preallocate and attempt fill in the first pass
263template <typename Counts, typename Neighbors, typename Tag>
264struct NeighborDiscriminatorCallback2D_FirstPass_BufferOptimization
265{
266 Counts counts;
267 Neighbors neighbors;
268#if ARBORX_VERSION >= 10799
269 template <typename Predicate, typename Geometry>
270 KOKKOS_FUNCTION void
271 operator()( Predicate const& predicate,
272 ArborX::PairValueIndex<Geometry, int> const& value_pair ) const
273 {
274 int const primitive_index = value_pair.index;
275 int const predicate_index = getData( predicate );
276 auto& count = counts( predicate_index );
277 if ( CollisionFilter<Tag>::keep( predicate_index, primitive_index ) )
278 {
279 if ( count < (int)neighbors.extent( 1 ) )
280 {
281 neighbors( predicate_index, count++ ) =
282 primitive_index; // WARNING see below**
283 }
284 else
285 {
286 count++;
287 }
288 }
289 }
290#else
291 template <typename Predicate>
292 KOKKOS_FUNCTION void operator()( Predicate const& predicate,
293 int primitive_index ) const
294 {
295 int const predicate_index = getData( predicate );
296 auto& count = counts( predicate_index );
297 if ( CollisionFilter<Tag>::keep( predicate_index, primitive_index ) )
298 {
299 if ( count < (int)neighbors.extent( 1 ) )
300 {
301 neighbors( predicate_index, count++ ) =
302 primitive_index; // WARNING see below**
303 }
304 else
305 {
306 count++;
307 }
308 }
309 }
310#endif
311};
312
313// Fill in the second pass
314template <typename Counts, typename Neighbors, typename Tag>
315struct NeighborDiscriminatorCallback2D_SecondPass
316{
317 Counts counts;
318 Neighbors neighbors;
319#if ARBORX_VERSION >= 10799
320 template <typename Predicate, typename Geometry>
321 KOKKOS_FUNCTION void
322 operator()( Predicate const& predicate,
323 ArborX::PairValueIndex<Geometry, int> const& value_pair ) const
324 {
325 int const primitive_index = value_pair.index;
326 int const predicate_index = getData( predicate );
327 auto& count = counts( predicate_index );
328 if ( CollisionFilter<Tag>::keep( predicate_index, primitive_index ) )
329 {
330 assert( count < (int)neighbors.extent( 1 ) );
331 neighbors( predicate_index, count++ ) =
332 primitive_index; // WARNING see below**
333 }
334 }
335#else
336 template <typename Predicate>
337 KOKKOS_FUNCTION void operator()( Predicate const& predicate,
338 int primitive_index ) const
339 {
340 int const predicate_index = getData( predicate );
341 auto& count = counts( predicate_index );
342 if ( CollisionFilter<Tag>::keep( predicate_index, primitive_index ) )
343 {
344 assert( count < (int)neighbors.extent( 1 ) );
345 neighbors( predicate_index, count++ ) =
346 primitive_index; // WARNING see below**
347 }
348 }
349#endif
350};
351
352// NOTE** Taking advantage of the knowledge that one predicate is processed by a
353// single thread. Count increment should be atomic otherwise.
354
356} // namespace Impl
357
358//---------------------------------------------------------------------------//
360template <typename MemorySpace, typename Tag>
362{
364 Kokkos::View<int*, MemorySpace> col_ind;
366 Kokkos::View<int*, MemorySpace> row_ptr;
368 typename MemorySpace::size_type shift;
370 typename MemorySpace::size_type total;
371};
372
373//---------------------------------------------------------------------------//
394template <typename ExecutionSpace, typename Positions, typename Tag>
395auto makeNeighborList( ExecutionSpace space, Tag, Positions const& positions,
396 typename Positions::size_type first,
397 typename Positions::size_type last,
398 typename Positions::value_type radius,
399 int buffer_size = 0 )
400{
401 assert( buffer_size >= 0 );
402 assert( last >= first );
403 assert( last <= positions.size() );
404
405 using memory_space = typename Positions::memory_space;
406
407#if ARBORX_VERSION >= 10799
408 ArborX::BoundingVolumeHierarchy bvh(
409 space, ArborX::Experimental::attach_indices<int>( positions ) );
410#else
411 ArborX::BVH<memory_space> bvh( space, positions );
412#endif
413
414 Kokkos::View<int*, memory_space> indices(
415 Kokkos::view_alloc( "indices", Kokkos::WithoutInitializing ), 0 );
416 Kokkos::View<int*, memory_space> offset(
417 Kokkos::view_alloc( "offset", Kokkos::WithoutInitializing ), 0 );
418 bvh.query(
419 space, Impl::makePredicates( positions, first, last, radius ),
420 Impl::NeighborDiscriminatorCallback<Tag>{}, indices, offset,
421 ArborX::Experimental::TraversalPolicy().setBufferSize( buffer_size ) );
422
424 std::move( indices ), std::move( offset ), first, bvh.size() };
425}
426
445template <typename Positions, typename Tag>
446auto makeNeighborList( Tag tag, Positions const& positions,
447 typename Positions::size_type first,
448 typename Positions::size_type last,
449 typename Positions::value_type radius,
450 int buffer_size = 0 )
451{
452 typename Positions::execution_space space{};
453 return makeNeighborList( space, tag, positions, first, last, radius,
454 buffer_size );
455}
456
457//---------------------------------------------------------------------------//
459template <typename MemorySpace, typename Tag>
460struct Dense
461{
463 Kokkos::View<int*, MemorySpace> cnt;
465 Kokkos::View<int**, MemorySpace> val;
467 typename MemorySpace::size_type shift;
469 typename MemorySpace::size_type total;
470};
471
472//---------------------------------------------------------------------------//
493template <typename ExecutionSpace, typename Positions, typename Tag>
494auto make2DNeighborList( ExecutionSpace space, Tag, Positions const& positions,
495 typename Positions::size_type first,
496 typename Positions::size_type last,
497 typename Positions::value_type radius,
498 int buffer_size = 0 )
499{
500 assert( buffer_size >= 0 );
501 assert( last >= first );
502 assert( last <= positions.size() );
503
504 using memory_space = typename Positions::memory_space;
505
506#if ARBORX_VERSION >= 10799
507 ArborX::BoundingVolumeHierarchy bvh(
508 space, ArborX::Experimental::attach_indices<int>( positions ) );
509#else
510 ArborX::BVH<memory_space> bvh( space, positions );
511#endif
512
513 auto const predicates =
514 Impl::makePredicates( positions, first, last, radius );
515
516 auto const n_queries =
517 ArborX::AccessTraits<std::remove_const_t<decltype( predicates )>
518#if ARBORX_VERSION < 10799
519 ,
520 ArborX::PredicatesTag
521#endif
522 >::size( predicates );
523
524 Kokkos::View<int**, memory_space> neighbors;
525 Kokkos::View<int*, memory_space> counts( "counts", n_queries );
526 if ( buffer_size > 0 )
527 {
528 neighbors = Kokkos::View<int**, memory_space>(
529 Kokkos::view_alloc( "neighbors", Kokkos::WithoutInitializing ),
530 n_queries, buffer_size );
531 bvh.query(
532 space, predicates,
533 Impl::NeighborDiscriminatorCallback2D_FirstPass_BufferOptimization<
534 decltype( counts ), decltype( neighbors ), Tag>{ counts,
535 neighbors } );
536 }
537 else
538 {
539 bvh.query(
540 space, predicates,
541 Impl::NeighborDiscriminatorCallback2D_FirstPass<decltype( counts ),
542 Tag>{ counts } );
543 }
544
545 auto const max_neighbors = Impl::max_reduce( space, counts );
546 if ( max_neighbors <= buffer_size )
547 {
548 // NOTE We do not bother shrinking to eliminate the excess allocation.
549 // NOTE If buffer_size is 0, neighbors is default constructed. This is
550 // fine with the current design/implementation of NeighborList access
551 // traits.
552 return Dense<memory_space, Tag>{ counts, neighbors, first, bvh.size() };
553 }
554
555 neighbors = Kokkos::View<int**, memory_space>(
556 Kokkos::view_alloc( "neighbors", Kokkos::WithoutInitializing ),
557 n_queries, max_neighbors ); // realloc storage for neighbors
558 Kokkos::deep_copy( counts, 0 ); // reset counts to zero
559 bvh.query( space, predicates,
560 Impl::NeighborDiscriminatorCallback2D_SecondPass<
561 decltype( counts ), decltype( neighbors ), Tag>{
562 counts, neighbors } );
563
564 return Dense<memory_space, Tag>{ counts, neighbors, first, bvh.size() };
565}
566
586template <typename Positions, typename Tag>
587auto make2DNeighborList( Tag tag, Positions const& positions,
588 typename Positions::size_type first,
589 typename Positions::size_type last,
590 typename Positions::value_type radius,
591 int buffer_size = 0 )
592{
593 using exec_space = typename Positions::execution_space;
594 return make2DNeighborList( exec_space{}, tag, positions, first, last,
595 radius, buffer_size );
596}
597
598} // namespace Experimental
599
601template <typename MemorySpace, typename Tag>
602class NeighborList<Experimental::CrsGraph<MemorySpace, Tag>>
603{
605 using size_type = std::size_t;
607 using crs_graph_type = Experimental::CrsGraph<MemorySpace, Tag>;
608
609 public:
611 using memory_space = MemorySpace;
612
614 KOKKOS_INLINE_FUNCTION
615 static size_type totalNeighbor( crs_graph_type const& crs_graph )
616 {
617 return Impl::totalNeighbor( crs_graph, crs_graph.total );
618 }
619
621 KOKKOS_INLINE_FUNCTION
622 static size_type maxNeighbor( crs_graph_type const& crs_graph )
623 {
624 return Impl::maxNeighbor( crs_graph, crs_graph.total );
625 }
626
628 static KOKKOS_FUNCTION size_type
629 numNeighbor( crs_graph_type const& crs_graph, size_type p )
630 {
631 assert( (int)p >= 0 && p < crs_graph.total );
632 p -= crs_graph.shift;
633 if ( (int)p < 0 || p >= crs_graph.row_ptr.size() - 1 )
634 return 0;
635 return crs_graph.row_ptr( p + 1 ) - crs_graph.row_ptr( p );
636 }
637
638 static KOKKOS_FUNCTION size_type
639 getNeighbor( crs_graph_type const& crs_graph, size_type p, size_type n )
640 {
641 assert( n < numNeighbor( crs_graph, p ) );
642 p -= crs_graph.shift;
643 return crs_graph.col_ind( crs_graph.row_ptr( p ) + n );
644 }
645};
646
648template <typename MemorySpace, typename Tag>
649class NeighborList<Experimental::Dense<MemorySpace, Tag>>
650{
652 using size_type = std::size_t;
654 using specialization_type = Experimental::Dense<MemorySpace, Tag>;
655
656 public:
658 using memory_space = MemorySpace;
659
661 KOKKOS_INLINE_FUNCTION
662 static size_type totalNeighbor( specialization_type const& d )
663 {
664 return Impl::totalNeighbor( d, d.total );
665 }
666
668 KOKKOS_INLINE_FUNCTION
669 static size_type maxNeighbor( specialization_type const& d )
670 {
671 return Impl::maxNeighbor( d, d.total );
672 }
673
675 static KOKKOS_FUNCTION size_type numNeighbor( specialization_type const& d,
676 size_type p )
677 {
678 assert( (int)p >= 0 && p < d.total );
679 p -= d.shift;
680 if ( (int)p < 0 || p >= d.cnt.size() )
681 return 0;
682 return d.cnt( p );
683 }
684
685 static KOKKOS_FUNCTION size_type getNeighbor( specialization_type const& d,
686 size_type p, size_type n )
687 {
688 assert( n < numNeighbor( d, p ) );
689 p -= d.shift;
690 return d.val( p, n );
691 }
692};
693
694} // namespace Cabana
695
696#endif
auto makeNeighborList(ExecutionSpace space, Tag, Positions const &positions, typename Positions::size_type first, typename Positions::size_type last, typename Positions::value_type radius, int buffer_size=0)
Neighbor list implementation using ArborX for particles within the interaction distance with a 1D com...
Definition Cabana_Experimental_NeighborList.hpp:395
auto make2DNeighborList(ExecutionSpace space, Tag, Positions const &positions, typename Positions::size_type first, typename Positions::size_type last, typename Positions::value_type radius, int buffer_size=0)
Neighbor list implementation using ArborX for particles within the interaction distance with a 2D lay...
Definition Cabana_Experimental_NeighborList.hpp:494
Neighbor list interface.
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
Slice a single particle property from an AoSoA.
Memory access type checking.
static KOKKOS_INLINE_FUNCTION size_type totalNeighbor(crs_graph_type const &crs_graph)
Get the total number of neighbors across all particles.
Definition Cabana_Experimental_NeighborList.hpp:615
static KOKKOS_FUNCTION size_type getNeighbor(crs_graph_type const &crs_graph, size_type p, size_type n)
Get the id for a neighbor for a given particle index and neighbor index.
Definition Cabana_Experimental_NeighborList.hpp:639
MemorySpace memory_space
Kokkos memory space.
Definition Cabana_Experimental_NeighborList.hpp:611
static KOKKOS_INLINE_FUNCTION size_type maxNeighbor(crs_graph_type const &crs_graph)
Get the maximum number of neighbors across all particles.
Definition Cabana_Experimental_NeighborList.hpp:622
static KOKKOS_FUNCTION size_type numNeighbor(crs_graph_type const &crs_graph, size_type p)
Get the number of neighbors for a given particle index.
Definition Cabana_Experimental_NeighborList.hpp:629
static KOKKOS_INLINE_FUNCTION size_type totalNeighbor(specialization_type const &d)
Get the total number of neighbors across all particles.
Definition Cabana_Experimental_NeighborList.hpp:662
static KOKKOS_FUNCTION size_type numNeighbor(specialization_type const &d, size_type p)
Get the number of neighbors for a given particle index.
Definition Cabana_Experimental_NeighborList.hpp:675
MemorySpace memory_space
Kokkos memory space.
Definition Cabana_Experimental_NeighborList.hpp:658
static KOKKOS_INLINE_FUNCTION size_type maxNeighbor(specialization_type const &d)
Get the maximum number of neighbors across all particles.
Definition Cabana_Experimental_NeighborList.hpp:669
static KOKKOS_FUNCTION size_type getNeighbor(specialization_type const &d, size_type p, size_type n)
Get the id for a neighbor for a given particle index and neighbor index.
Definition Cabana_Experimental_NeighborList.hpp:685
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.
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
static KOKKOS_FUNCTION auto get(PositionLike const &x, size_type i)
Get the particle at the index.
Definition Cabana_Experimental_NeighborList.hpp:155
static KOKKOS_FUNCTION size_type size(PositionLike const &x)
Get number of particles.
Definition Cabana_Experimental_NeighborList.hpp:150
typename PositionLike::memory_space memory_space
Kokkos memory space.
Definition Cabana_Experimental_NeighborList.hpp:146
typename PositionLike::size_type size_type
Size type.
Definition Cabana_Experimental_NeighborList.hpp:148
Cabana::Experimental::Impl::SubPositionsAndRadius< Positions > PositionLike
Position wrapper with partial range and radius information.
Definition Cabana_Experimental_NeighborList.hpp:143
static KOKKOS_FUNCTION size_type size(Positions const &x)
Get number of particles.
Definition Cabana_Experimental_NeighborList.hpp:121
typename Positions::size_type size_type
Size type.
Definition Cabana_Experimental_NeighborList.hpp:119
typename Positions::memory_space memory_space
Kokkos memory space.
Definition Cabana_Experimental_NeighborList.hpp:117
static KOKKOS_FUNCTION auto get(Positions const &x, size_type i)
Get the particle at the index.
Definition Cabana_Experimental_NeighborList.hpp:126
1d ArborX neighbor list storage layout.
Definition Cabana_Experimental_NeighborList.hpp:362
Kokkos::View< int *, MemorySpace > row_ptr
Neighbor offsets.
Definition Cabana_Experimental_NeighborList.hpp:366
MemorySpace::size_type total
Total particles.
Definition Cabana_Experimental_NeighborList.hpp:370
MemorySpace::size_type shift
Neighbor offset shift.
Definition Cabana_Experimental_NeighborList.hpp:368
Kokkos::View< int *, MemorySpace > col_ind
Neighbor indices.
Definition Cabana_Experimental_NeighborList.hpp:364
2d ArborX neighbor list storage layout.
Definition Cabana_Experimental_NeighborList.hpp:461
MemorySpace::size_type total
Total particles.
Definition Cabana_Experimental_NeighborList.hpp:469
Kokkos::View< int *, MemorySpace > cnt
Neighbor counts.
Definition Cabana_Experimental_NeighborList.hpp:463
MemorySpace::size_type shift
Neighbor offset shift.
Definition Cabana_Experimental_NeighborList.hpp:467
Kokkos::View< int **, MemorySpace > val
Neighbor indices.
Definition Cabana_Experimental_NeighborList.hpp:465