From 24dfbb47512b03f2b370e7499f2adff746f4038a Mon Sep 17 00:00:00 2001 From: "Automatic Deployment (GitHub Action)" Date: Fri, 7 Feb 2025 18:17:26 +0000 Subject: [PATCH] Documentation Update --- doxygen/Cabana__VerletList_8hpp_source.html | 1576 +++++++++-------- .../classCabana_1_1VerletList-members.html | 3 + doxygen/classCabana_1_1VerletList.html | 106 +- doxygen/doxygen_crawl.html | 3 + doxygen/search/all_16.js | 2 +- doxygen/search/all_2.js | 2 +- doxygen/search/functions_1.js | 2 +- doxygen/search/functions_15.js | 2 +- 8 files changed, 985 insertions(+), 711 deletions(-) diff --git a/doxygen/Cabana__VerletList_8hpp_source.html b/doxygen/Cabana__VerletList_8hpp_source.html index 72323e1fd..f89f3c752 100644 --- a/doxygen/Cabana__VerletList_8hpp_source.html +++ b/doxygen/Cabana__VerletList_8hpp_source.html @@ -210,734 +210,898 @@
123//---------------------------------------------------------------------------//
124// Verlet List Builder
125//---------------------------------------------------------------------------//
-
126template <class DeviceType, class PositionType, class RandomAccessPositionType,
+
126template <class DeviceType, class RandomAccessPositionType, class RadiusType,
127 class AlgorithmTag, class LayoutTag, class BuildOpTag>
128struct VerletListBuilder
129{
130 // Types.
131 using device = DeviceType;
-
132 using PositionValueType = typename PositionType::value_type;
+
132 using PositionValueType = typename RandomAccessPositionType::value_type;
133 using memory_space = typename device::memory_space;
134 using execution_space = typename device::execution_space;
135
136 // List data.
137 VerletListData<memory_space, LayoutTag> _data;
-
138
-
139 // Neighbor cutoff.
-
140 PositionValueType rsqr;
-
141
-
142 // Positions.
-
143 RandomAccessPositionType _position;
-
144 std::size_t pid_begin, pid_end;
-
145
-
146 // Binning Data.
-
147 BinningData<memory_space> bin_data_1d;
-
148 LinkedCellList<memory_space, PositionValueType> linked_cell_list;
-
149
-
150 // Check to count or refill.
-
151 bool refill;
-
152 bool count;
-
153
-
154 // Maximum allocated neighbors per particle
-
155 std::size_t alloc_n;
-
156
-
157 // Constructor.
-
158 VerletListBuilder( PositionType positions, const std::size_t begin,
-
159 const std::size_t end,
-
160 const PositionValueType neighborhood_radius,
-
161 const PositionValueType cell_size_ratio,
-
162 const PositionValueType grid_min[3],
-
163 const PositionValueType grid_max[3],
-
164 const std::size_t max_neigh )
-
165 : pid_begin( begin )
-
166 , pid_end( end )
-
167 , alloc_n( max_neigh )
-
168 {
-
169 count = true;
-
170 refill = false;
-
171
-
172 // Create the count view.
-
173 _data.counts = Kokkos::View<int*, memory_space>( "num_neighbors",
-
174 size( positions ) );
-
175
-
176 // Make a guess for the number of neighbors per particle for 2D lists.
-
177 initCounts( LayoutTag() );
-
178
-
179 // Shallow copy for random access read-only memory.
-
180 _position = positions;
-
181
-
182 // Bin the particles in the grid. Don't actually sort them but make a
-
183 // permutation vector. Note that we are binning all particles here and
-
184 // not just the requested range. This is because all particles are
-
185 // treated as candidates for neighbors.
-
186 double grid_size = cell_size_ratio * neighborhood_radius;
-
187 PositionValueType grid_delta[3] = { grid_size, grid_size, grid_size };
-
188 linked_cell_list = createLinkedCellList<memory_space>(
-
189 _position, grid_delta, grid_min, grid_max, neighborhood_radius,
-
190 cell_size_ratio );
-
191 bin_data_1d = linked_cell_list.binningData();
-
192
-
193 // We will use the square of the distance for neighbor determination.
-
194 rsqr = neighborhood_radius * neighborhood_radius;
-
195 }
+
138 // Background squared neighbor cutoff.
+
139 PositionValueType rsqr;
+
140 // Fixed or per-particle neighbor radius.
+
141 RadiusType radius;
+
142
+
143 // Positions.
+
144 RandomAccessPositionType _position;
+
145 std::size_t pid_begin, pid_end;
+
146
+
147 // Binning Data.
+
148 BinningData<memory_space> bin_data_1d;
+
149 LinkedCellList<memory_space, PositionValueType> linked_cell_list;
+
150
+
151 // Check to count or refill.
+
152 bool refill;
+
153 bool count;
+
154
+
155 // Maximum allocated neighbors per particle
+
156 std::size_t alloc_n;
+
157
+
158 // Constructor with a single cutoff radius.
+
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 )
+
167 : pid_begin( begin )
+
168 , pid_end( end )
+
169 , alloc_n( max_neigh )
+
170 {
+
171 init( positions, neighborhood_radius, cell_size_ratio, grid_min,
+
172 grid_max );
+
173 // This value is not currently used, but set to be consistent with the
+
174 // variable cutoff case below.
+
175 radius = neighborhood_radius;
+
176 }
+
177
+
178 // Constructor with a background radius (used for the LinkedCellList) and a
+
179 // per-particle 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 )
+
189 : pid_begin( begin )
+
190 , pid_end( end )
+
191 , alloc_n( max_neigh )
+
192 {
+
193 assert( positions.size() == neighborhood_radius.size() );
+
194 init( positions, background_radius, cell_size_ratio, grid_min,
+
195 grid_max );
196
-
197 // Neighbor count team operator (only used for CSR lists).
-
198 struct CountNeighborsTag
-
199 {
-
200 };
-
201 using CountNeighborsPolicy =
-
202 Kokkos::TeamPolicy<execution_space, CountNeighborsTag,
-
203 Kokkos::IndexType<int>,
-
204 Kokkos::Schedule<Kokkos::Dynamic>>;
-
205
-
206 KOKKOS_INLINE_FUNCTION
-
207 void
-
208 operator()( const CountNeighborsTag&,
-
209 const typename CountNeighborsPolicy::member_type& team ) const
-
210 {
-
211 // The league rank of the team is the cardinal cell index we are
-
212 // working on.
-
213 int cell = team.league_rank();
-
214
-
215 // Get the stencil for this cell.
-
216 int imin, imax, jmin, jmax, kmin, kmax;
-
217 linked_cell_list.getStencilCells( cell, imin, imax, jmin, jmax, kmin,
-
218 kmax );
+
197 // Store a shallow copy (not squared).
+
198 // TODO: for cases where the radii never change, this could be better
+
199 // optimized with a deep copy of the squared radius instead.
+
200 radius = neighborhood_radius;
+
201 }
+
202
+
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] )
+
209 {
+
210 count = true;
+
211 refill = false;
+
212
+
213 // Create the count view.
+
214 _data.counts = Kokkos::View<int*, memory_space>( "num_neighbors",
+
215 size( positions ) );
+
216
+
217 // Make a guess for the number of neighbors per particle for 2D lists.
+
218 initCounts( LayoutTag() );
219
-
220 // Operate on the particles in the bin.
-
221 std::size_t b_offset = bin_data_1d.binOffset( cell );
-
222 Kokkos::parallel_for(
-
223 Kokkos::TeamThreadRange( team, 0, bin_data_1d.binSize( cell ) ),
-
224 [&]( const int bi )
-
225 {
-
226 // Get the true particle id. The binned particle index is the
-
227 // league rank of the team.
-
228 std::size_t pid = linked_cell_list.permutation( bi + b_offset );
-
229
-
230 if ( ( pid >= pid_begin ) && ( pid < pid_end ) )
-
231 {
-
232 // Cache the particle coordinates.
-
233 double x_p = _position( pid, 0 );
-
234 double y_p = _position( pid, 1 );
-
235 double z_p = _position( pid, 2 );
-
236
-
237 // Loop over the cell stencil.
-
238 int stencil_count = 0;
-
239 for ( int i = imin; i < imax; ++i )
-
240 for ( int j = jmin; j < jmax; ++j )
-
241 for ( int k = kmin; k < kmax; ++k )
-
242 {
-
243 // See if we should actually check this box for
-
244 // neighbors.
-
245 if ( linked_cell_list.cellStencil()
-
246 .grid.minDistanceToPoint(
-
247 x_p, y_p, z_p, i, j, k ) <= rsqr )
-
248 {
-
249 std::size_t n_offset =
-
250 linked_cell_list.binOffset( i, j, k );
-
251 std::size_t num_n =
-
252 linked_cell_list.binSize( i, j, k );
-
253
-
254 // Check the particles in this bin to see if
-
255 // they are neighbors. If they are add to
-
256 // the count for this bin.
-
257 int cell_count = 0;
-
258 neighbor_reduce( team, pid, x_p, y_p, z_p,
-
259 n_offset, num_n,
-
260 cell_count, BuildOpTag() );
-
261 stencil_count += cell_count;
-
262 }
-
263 }
-
264 Kokkos::single( Kokkos::PerThread( team ), [&]()
-
265 { _data.counts( pid ) = stencil_count; } );
-
266 }
-
267 } );
-
268 }
-
269
-
270 // Neighbor count team vector loop (only used for CSR lists).
-
271 KOKKOS_INLINE_FUNCTION void
-
272 neighbor_reduce( const typename CountNeighborsPolicy::member_type& team,
-
273 const std::size_t pid, const double x_p, const double y_p,
-
274 const double z_p, const int n_offset, const int num_n,
-
275 int& cell_count, TeamVectorOpTag ) const
-
276 {
-
277 Kokkos::parallel_reduce(
-
278 Kokkos::ThreadVectorRange( team, num_n ),
-
279 [&]( const int n, int& local_count ) {
-
280 neighbor_kernel( pid, x_p, y_p, z_p, n_offset, n, local_count );
-
281 },
-
282 cell_count );
-
283 }
-
284
-
285 // Neighbor count serial loop (only used for CSR lists).
-
286 KOKKOS_INLINE_FUNCTION
-
287 void neighbor_reduce( const typename CountNeighborsPolicy::member_type,
-
288 const std::size_t pid, const double x_p,
-
289 const double y_p, const double z_p,
-
290 const int n_offset, const int num_n, int& cell_count,
-
291 TeamOpTag ) const
-
292 {
-
293 for ( int n = 0; n < num_n; n++ )
-
294 neighbor_kernel( pid, x_p, y_p, z_p, n_offset, n, cell_count );
-
295 }
-
296
-
297 // Neighbor count kernel
-
298 KOKKOS_INLINE_FUNCTION
-
299 void neighbor_kernel( const int pid, const double x_p, const double y_p,
-
300 const double z_p, const int n_offset, const int n,
-
301 int& local_count ) const
-
302 {
-
303 // Get the true id of the candidate neighbor.
-
304 std::size_t nid = linked_cell_list.permutation( n_offset + n );
-
305
-
306 // Cache the candidate neighbor particle coordinates.
-
307 double x_n = _position( nid, 0 );
-
308 double y_n = _position( nid, 1 );
-
309 double z_n = _position( nid, 2 );
-
310
-
311 // If this could be a valid neighbor, continue.
-
312 if ( NeighborDiscriminator<AlgorithmTag>::isValid(
-
313 pid, x_p, y_p, z_p, nid, x_n, y_n, z_n ) )
-
314 {
-
315 // Calculate the distance between the particle and its candidate
-
316 // neighbor.
-
317 PositionValueType dx = x_p - x_n;
-
318 PositionValueType dy = y_p - y_n;
-
319 PositionValueType dz = z_p - z_n;
-
320 PositionValueType dist_sqr = dx * dx + dy * dy + dz * dz;
-
321
-
322 // If within the cutoff add to the count.
-
323 if ( dist_sqr <= rsqr )
-
324 local_count += 1;
-
325 }
-
326 }
-
327
-
328 // Process the CSR counts by computing offsets and allocating the neighbor
-
329 // list.
-
330 template <class KokkosMemorySpace>
-
331 struct OffsetScanOp
-
332 {
-
333 using kokkos_mem_space = KokkosMemorySpace;
-
334 Kokkos::View<int*, kokkos_mem_space> counts;
-
335 Kokkos::View<int*, kokkos_mem_space> offsets;
-
336 KOKKOS_INLINE_FUNCTION
-
337 void operator()( const int i, int& update, const bool final_pass ) const
-
338 {
-
339 if ( final_pass )
-
340 offsets( i ) = update;
-
341 update += counts( i );
-
342 }
-
343 };
-
344
-
345 void initCounts( VerletLayoutCSR ) {}
-
346
-
347 void initCounts( VerletLayout2D )
-
348 {
-
349 if ( alloc_n > 0 )
-
350 {
-
351 count = false;
-
352
-
353 _data.neighbors = Kokkos::View<int**, memory_space>(
-
354 Kokkos::ViewAllocateWithoutInitializing( "neighbors" ),
-
355 _data.counts.size(), alloc_n );
-
356 }
-
357 }
+
220 // Shallow copy for random access read-only memory.
+
221 _position = positions;
+
222
+
223 // Bin the particles in the grid. Don't actually sort them but make a
+
224 // permutation vector. Note that we are binning all particles here and
+
225 // not just the requested range. This is because all particles are
+
226 // treated as candidates for neighbors.
+
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,
+
231 cell_size_ratio );
+
232 bin_data_1d = linked_cell_list.binningData();
+
233
+
234 // We will use the square of the distance for neighbor determination.
+
235 rsqr = neighborhood_radius * neighborhood_radius;
+
236 }
+
237
+
238 KOKKOS_INLINE_FUNCTION auto cutoff( [[maybe_unused]] const int p ) const
+
239 {
+
240 // Square the radius on the fly if using a per-particle field to avoid a
+
241 // deep copy.
+
242 if constexpr ( is_slice<RadiusType>::value ||
+
243 Kokkos::is_view<RadiusType>::value )
+
244 return radius( p ) * radius( p );
+
245 // This value is already squared.
+
246 else
+
247 return rsqr;
+
248 }
+
249
+
250 // Neighbor count team operator (only used for CSR lists).
+
251 struct CountNeighborsTag
+
252 {
+
253 };
+
254 using CountNeighborsPolicy =
+
255 Kokkos::TeamPolicy<execution_space, CountNeighborsTag,
+
256 Kokkos::IndexType<int>,
+
257 Kokkos::Schedule<Kokkos::Dynamic>>;
+
258
+
259 KOKKOS_INLINE_FUNCTION
+
260 void
+
261 operator()( const CountNeighborsTag&,
+
262 const typename CountNeighborsPolicy::member_type& team ) const
+
263 {
+
264 // The league rank of the team is the cardinal cell index we are
+
265 // working on.
+
266 int cell = team.league_rank();
+
267
+
268 // Get the stencil for this cell.
+
269 int imin, imax, jmin, jmax, kmin, kmax;
+
270 linked_cell_list.getStencilCells( cell, imin, imax, jmin, jmax, kmin,
+
271 kmax );
+
272
+
273 // Operate on the particles in the bin.
+
274 std::size_t b_offset = bin_data_1d.binOffset( cell );
+
275 Kokkos::parallel_for(
+
276 Kokkos::TeamThreadRange( team, 0, bin_data_1d.binSize( cell ) ),
+
277 [&]( const int bi )
+
278 {
+
279 // Get the true particle id. The binned particle index is the
+
280 // league rank of the team.
+
281 std::size_t pid = linked_cell_list.permutation( bi + b_offset );
+
282
+
283 if ( ( pid >= pid_begin ) && ( pid < pid_end ) )
+
284 {
+
285 // Cache the particle coordinates.
+
286 double x_p = _position( pid, 0 );
+
287 double y_p = _position( pid, 1 );
+
288 double z_p = _position( pid, 2 );
+
289
+
290 // Loop over the cell stencil.
+
291 int stencil_count = 0;
+
292 for ( int i = imin; i < imax; ++i )
+
293 for ( int j = jmin; j < jmax; ++j )
+
294 for ( int k = kmin; k < kmax; ++k )
+
295 {
+
296 // See if we should actually check this box for
+
297 // neighbors.
+
298 if ( linked_cell_list.cellStencil()
+
299 .grid.minDistanceToPoint(
+
300 x_p, y_p, z_p, i, j, k ) <= rsqr )
+
301 {
+
302 std::size_t n_offset =
+
303 linked_cell_list.binOffset( i, j, k );
+
304 std::size_t num_n =
+
305 linked_cell_list.binSize( i, j, k );
+
306
+
307 // Check the particles in this bin to see if
+
308 // they are neighbors. If they are add to
+
309 // the count for this bin.
+
310 int cell_count = 0;
+
311 neighbor_reduce( team, pid, x_p, y_p, z_p,
+
312 n_offset, num_n,
+
313 cell_count, BuildOpTag() );
+
314 stencil_count += cell_count;
+
315 }
+
316 }
+
317 Kokkos::single( Kokkos::PerThread( team ), [&]()
+
318 { _data.counts( pid ) = stencil_count; } );
+
319 }
+
320 } );
+
321 }
+
322
+
323 // Neighbor count team vector loop (only used for CSR lists).
+
324 KOKKOS_INLINE_FUNCTION void
+
325 neighbor_reduce( const typename CountNeighborsPolicy::member_type& team,
+
326 const std::size_t pid, const double x_p, const double y_p,
+
327 const double z_p, const int n_offset, const int num_n,
+
328 int& cell_count, TeamVectorOpTag ) const
+
329 {
+
330 Kokkos::parallel_reduce(
+
331 Kokkos::ThreadVectorRange( team, num_n ),
+
332 [&]( const int n, int& local_count ) {
+
333 neighbor_kernel( pid, x_p, y_p, z_p, n_offset, n, local_count );
+
334 },
+
335 cell_count );
+
336 }
+
337
+
338 // Neighbor count serial loop (only used for CSR lists).
+
339 KOKKOS_INLINE_FUNCTION
+
340 void neighbor_reduce( const typename CountNeighborsPolicy::member_type,
+
341 const std::size_t pid, const double x_p,
+
342 const double y_p, const double z_p,
+
343 const int n_offset, const int num_n, int& cell_count,
+
344 TeamOpTag ) const
+
345 {
+
346 for ( int n = 0; n < num_n; n++ )
+
347 neighbor_kernel( pid, x_p, y_p, z_p, n_offset, n, cell_count );
+
348 }
+
349
+
350 // Neighbor count kernel
+
351 KOKKOS_INLINE_FUNCTION
+
352 void neighbor_kernel( const int pid, const double x_p, const double y_p,
+
353 const double z_p, const int n_offset, const int n,
+
354 int& local_count ) const
+
355 {
+
356 // Get the true id of the candidate neighbor.
+
357 std::size_t nid = linked_cell_list.permutation( n_offset + n );
358
-
359 void processCounts( VerletLayoutCSR )
-
360 {
-
361 // Allocate offsets.
-
362 _data.offsets = Kokkos::View<int*, memory_space>(
-
363 Kokkos::ViewAllocateWithoutInitializing( "neighbor_offsets" ),
-
364 _data.counts.size() );
-
365
-
366 // Calculate offsets from counts and the total number of counts.
-
367 OffsetScanOp<memory_space> offset_op;
-
368 offset_op.counts = _data.counts;
-
369 offset_op.offsets = _data.offsets;
-
370 int total_num_neighbor;
-
371 Kokkos::RangePolicy<execution_space> range_policy(
-
372 0, _data.counts.extent( 0 ) );
-
373 Kokkos::parallel_scan( "Cabana::VerletListBuilder::offset_scan",
-
374 range_policy, offset_op, total_num_neighbor );
-
375 Kokkos::fence();
-
376
-
377 // Allocate the neighbor list.
-
378 _data.neighbors = Kokkos::View<int*, memory_space>(
-
379 Kokkos::ViewAllocateWithoutInitializing( "neighbors" ),
-
380 total_num_neighbor );
-
381
-
382 // Reset the counts. We count again when we fill.
-
383 Kokkos::deep_copy( _data.counts, 0 );
-
384 }
-
385
-
386 // Process 2D counts by computing the maximum number of neighbors and
-
387 // reallocating the 2D data structure if needed.
-
388 void processCounts( VerletLayout2D )
-
389 {
-
390 // Calculate the maximum number of neighbors.
-
391 auto counts = _data.counts;
-
392 int max;
-
393 Kokkos::Max<int> max_reduce( max );
-
394 Kokkos::parallel_reduce(
-
395 "Cabana::VerletListBuilder::reduce_max",
-
396 Kokkos::RangePolicy<execution_space>( 0, _data.counts.size() ),
-
397 KOKKOS_LAMBDA( const int i, int& value ) {
-
398 if ( counts( i ) > value )
-
399 value = counts( i );
-
400 },
-
401 max_reduce );
-
402 Kokkos::fence();
-
403 _data.max_n = static_cast<std::size_t>( max );
-
404
-
405 // Reallocate the neighbor list if previous size is exceeded.
-
406 if ( count or _data.max_n > _data.neighbors.extent( 1 ) )
-
407 {
-
408 refill = true;
-
409 Kokkos::deep_copy( _data.counts, 0 );
-
410 _data.neighbors = Kokkos::View<int**, memory_space>(
-
411 Kokkos::ViewAllocateWithoutInitializing( "neighbors" ),
-
412 _data.counts.size(), _data.max_n );
-
413 }
-
414 }
-
415
-
416 // Neighbor count team operator.
-
417 struct FillNeighborsTag
-
418 {
-
419 };
-
420 using FillNeighborsPolicy =
-
421 Kokkos::TeamPolicy<execution_space, FillNeighborsTag,
-
422 Kokkos::IndexType<int>,
-
423 Kokkos::Schedule<Kokkos::Dynamic>>;
-
424 KOKKOS_INLINE_FUNCTION
-
425 void
-
426 operator()( const FillNeighborsTag&,
-
427 const typename FillNeighborsPolicy::member_type& team ) const
-
428 {
-
429 // The league rank of the team is the cardinal cell index we are
-
430 // working on.
-
431 int cell = team.league_rank();
-
432
-
433 // Get the stencil for this cell.
-
434 int imin, imax, jmin, jmax, kmin, kmax;
-
435 linked_cell_list.getStencilCells( cell, imin, imax, jmin, jmax, kmin,
-
436 kmax );
-
437
-
438 // Operate on the particles in the bin.
-
439 std::size_t b_offset = bin_data_1d.binOffset( cell );
-
440 Kokkos::parallel_for(
-
441 Kokkos::TeamThreadRange( team, 0, bin_data_1d.binSize( cell ) ),
-
442 [&]( const int bi )
-
443 {
-
444 // Get the true particle id. The binned particle index is the
-
445 // league rank of the team.
-
446 std::size_t pid = linked_cell_list.permutation( bi + b_offset );
-
447
-
448 if ( ( pid >= pid_begin ) && ( pid < pid_end ) )
-
449 {
-
450 // Cache the particle coordinates.
-
451 double x_p = _position( pid, 0 );
-
452 double y_p = _position( pid, 1 );
-
453 double z_p = _position( pid, 2 );
-
454
-
455 // Loop over the cell stencil.
-
456 for ( int i = imin; i < imax; ++i )
-
457 for ( int j = jmin; j < jmax; ++j )
-
458 for ( int k = kmin; k < kmax; ++k )
-
459 {
-
460 // See if we should actually check this box for
-
461 // neighbors.
-
462 if ( linked_cell_list.cellStencil()
-
463 .grid.minDistanceToPoint(
-
464 x_p, y_p, z_p, i, j, k ) <= rsqr )
-
465 {
-
466 // Check the particles in this bin to see if
-
467 // they are neighbors.
-
468 std::size_t n_offset =
-
469 linked_cell_list.binOffset( i, j, k );
-
470 int num_n =
-
471 linked_cell_list.binSize( i, j, k );
-
472 neighbor_for( team, pid, x_p, y_p, z_p,
-
473 n_offset, num_n,
-
474 BuildOpTag() );
-
475 }
-
476 }
-
477 }
-
478 } );
-
479 }
-
480
-
481 // Neighbor fill team vector loop.
-
482 KOKKOS_INLINE_FUNCTION void
-
483 neighbor_for( const typename FillNeighborsPolicy::member_type& team,
-
484 const std::size_t pid, const double x_p, const double y_p,
-
485 const double z_p, const int n_offset, const int num_n,
-
486 TeamVectorOpTag ) const
-
487 {
-
488 Kokkos::parallel_for(
-
489 Kokkos::ThreadVectorRange( team, num_n ), [&]( const int n )
-
490 { neighbor_kernel( pid, x_p, y_p, z_p, n_offset, n ); } );
-
491 }
-
492
-
493 // Neighbor fill serial loop.
-
494 KOKKOS_INLINE_FUNCTION
-
495 void neighbor_for( const typename FillNeighborsPolicy::member_type team,
-
496 const std::size_t pid, const double x_p,
-
497 const double y_p, const double z_p, const int n_offset,
-
498 const int num_n, TeamOpTag ) const
-
499 {
-
500 for ( int n = 0; n < num_n; n++ )
-
501 Kokkos::single(
-
502 Kokkos::PerThread( team ),
-
503 [&]() { neighbor_kernel( pid, x_p, y_p, z_p, n_offset, n ); } );
-
504 }
-
505
-
506 // Neighbor fill kernel.
-
507 KOKKOS_INLINE_FUNCTION
-
508 void neighbor_kernel( const int pid, const double x_p, const double y_p,
-
509 const double z_p, const int n_offset,
-
510 const int n ) const
-
511 {
-
512 // Get the true id of the candidate neighbor.
-
513 std::size_t nid = linked_cell_list.permutation( n_offset + n );
-
514
-
515 // Cache the candidate neighbor particle coordinates.
-
516 double x_n = _position( nid, 0 );
-
517 double y_n = _position( nid, 1 );
-
518 double z_n = _position( nid, 2 );
-
519
-
520 // If this could be a valid neighbor, continue.
-
521 if ( NeighborDiscriminator<AlgorithmTag>::isValid(
-
522 pid, x_p, y_p, z_p, nid, x_n, y_n, z_n ) )
-
523 {
-
524 // Calculate the distance between the particle and its candidate
-
525 // neighbor.
-
526 PositionValueType dx = x_p - x_n;
-
527 PositionValueType dy = y_p - y_n;
-
528 PositionValueType dz = z_p - z_n;
-
529 PositionValueType dist_sqr = dx * dx + dy * dy + dz * dz;
-
530
-
531 // If within the cutoff increment the neighbor count and add as a
-
532 // neighbor at that index.
-
533 if ( dist_sqr <= rsqr )
-
534 {
-
535 _data.addNeighbor( pid, nid );
-
536 }
-
537 }
-
538 }
-
539};
-
540
-
541// Builder creation functions. This is only necessary to define the different
-
542// random access types.
-
543template <class DeviceType, class PositionType, class AlgorithmTag,
-
544 class LayoutTag, class BuildOpTag>
-
545auto createVerletListBuilder(
-
546 PositionType x, const std::size_t begin, const std::size_t end,
-
547 const typename PositionType::value_type radius,
-
548 const typename PositionType::value_type cell_size_ratio,
-
549 const typename PositionType::value_type grid_min[3],
-
550 const typename PositionType::value_type grid_max[3],
-
551 const std::size_t max_neigh,
-
552 typename std::enable_if<( is_slice<PositionType>::value ), int>::type* = 0 )
-
553{
-
554 using RandomAccessPositionType = typename PositionType::random_access_slice;
-
555 return VerletListBuilder<DeviceType, PositionType, RandomAccessPositionType,
-
556 AlgorithmTag, LayoutTag, BuildOpTag>(
-
557 x, begin, end, radius, cell_size_ratio, grid_min, grid_max, max_neigh );
-
558}
-
559
-
560template <class DeviceType, class PositionType, class AlgorithmTag,
-
561 class LayoutTag, class BuildOpTag>
-
562auto createVerletListBuilder(
-
563 PositionType x, const std::size_t begin, const std::size_t end,
-
564 const typename PositionType::value_type radius,
-
565 const typename PositionType::value_type cell_size_ratio,
-
566 const typename PositionType::value_type grid_min[3],
-
567 const typename PositionType::value_type grid_max[3],
-
568 const std::size_t max_neigh,
-
569 typename std::enable_if<( Kokkos::is_view<PositionType>::value ),
-
570 int>::type* = 0 )
-
571{
-
572 using RandomAccessPositionType =
-
573 Kokkos::View<typename PositionType::value_type**, DeviceType,
-
574 Kokkos::MemoryTraits<Kokkos::RandomAccess>>;
-
575 return VerletListBuilder<DeviceType, PositionType, RandomAccessPositionType,
-
576 AlgorithmTag, LayoutTag, BuildOpTag>(
-
577 x, begin, end, radius, cell_size_ratio, grid_min, grid_max, max_neigh );
-
578}
-
579
-
580//---------------------------------------------------------------------------//
-
581
-
583} // end namespace Impl
-
584
-
585//---------------------------------------------------------------------------//
-
603template <class MemorySpace, class AlgorithmTag, class LayoutTag,
-
604 class BuildTag = TeamVectorOpTag>
-
- +
359 // Cache the candidate neighbor particle coordinates.
+
360 double x_n = _position( nid, 0 );
+
361 double y_n = _position( nid, 1 );
+
362 double z_n = _position( nid, 2 );
+
363
+
364 // If this could be a valid neighbor, continue.
+
365 if ( NeighborDiscriminator<AlgorithmTag>::isValid(
+
366 pid, x_p, y_p, z_p, nid, x_n, y_n, z_n ) )
+
367 {
+
368 // Calculate the distance between the particle and its candidate
+
369 // neighbor.
+
370 PositionValueType dx = x_p - x_n;
+
371 PositionValueType dy = y_p - y_n;
+
372 PositionValueType dz = z_p - z_n;
+
373 PositionValueType dist_sqr = dx * dx + dy * dy + dz * dz;
+
374
+
375 // If within the cutoff add to the count.
+
376 if ( dist_sqr <= cutoff( pid ) )
+
377 local_count += 1;
+
378 }
+
379 }
+
380
+
381 // Process the CSR counts by computing offsets and allocating the neighbor
+
382 // list.
+
383 template <class KokkosMemorySpace>
+
384 struct OffsetScanOp
+
385 {
+
386 using kokkos_mem_space = KokkosMemorySpace;
+
387 Kokkos::View<int*, kokkos_mem_space> counts;
+
388 Kokkos::View<int*, kokkos_mem_space> offsets;
+
389 KOKKOS_INLINE_FUNCTION
+
390 void operator()( const int i, int& update, const bool final_pass ) const
+
391 {
+
392 if ( final_pass )
+
393 offsets( i ) = update;
+
394 update += counts( i );
+
395 }
+
396 };
+
397
+
398 void initCounts( VerletLayoutCSR ) {}
+
399
+
400 void initCounts( VerletLayout2D )
+
401 {
+
402 if ( alloc_n > 0 )
+
403 {
+
404 count = false;
+
405
+
406 _data.neighbors = Kokkos::View<int**, memory_space>(
+
407 Kokkos::ViewAllocateWithoutInitializing( "neighbors" ),
+
408 _data.counts.size(), alloc_n );
+
409 }
+
410 }
+
411
+
412 void processCounts( VerletLayoutCSR )
+
413 {
+
414 // Allocate offsets.
+
415 _data.offsets = Kokkos::View<int*, memory_space>(
+
416 Kokkos::ViewAllocateWithoutInitializing( "neighbor_offsets" ),
+
417 _data.counts.size() );
+
418
+
419 // Calculate offsets from counts and the total number of counts.
+
420 OffsetScanOp<memory_space> offset_op;
+
421 offset_op.counts = _data.counts;
+
422 offset_op.offsets = _data.offsets;
+
423 int total_num_neighbor;
+
424 Kokkos::RangePolicy<execution_space> range_policy(
+
425 0, _data.counts.extent( 0 ) );
+
426 Kokkos::parallel_scan( "Cabana::VerletListBuilder::offset_scan",
+
427 range_policy, offset_op, total_num_neighbor );
+
428 Kokkos::fence();
+
429
+
430 // Allocate the neighbor list.
+
431 _data.neighbors = Kokkos::View<int*, memory_space>(
+
432 Kokkos::ViewAllocateWithoutInitializing( "neighbors" ),
+
433 total_num_neighbor );
+
434
+
435 // Reset the counts. We count again when we fill.
+
436 Kokkos::deep_copy( _data.counts, 0 );
+
437 }
+
438
+
439 // Process 2D counts by computing the maximum number of neighbors and
+
440 // reallocating the 2D data structure if needed.
+
441 void processCounts( VerletLayout2D )
+
442 {
+
443 // Calculate the maximum number of neighbors.
+
444 auto counts = _data.counts;
+
445 int max;
+
446 Kokkos::Max<int> max_reduce( max );
+
447 Kokkos::parallel_reduce(
+
448 "Cabana::VerletListBuilder::reduce_max",
+
449 Kokkos::RangePolicy<execution_space>( 0, _data.counts.size() ),
+
450 KOKKOS_LAMBDA( const int i, int& value ) {
+
451 if ( counts( i ) > value )
+
452 value = counts( i );
+
453 },
+
454 max_reduce );
+
455 Kokkos::fence();
+
456 _data.max_n = static_cast<std::size_t>( max );
+
457
+
458 // Reallocate the neighbor list if previous size is exceeded.
+
459 if ( count or _data.max_n > _data.neighbors.extent( 1 ) )
+
460 {
+
461 refill = true;
+
462 Kokkos::deep_copy( _data.counts, 0 );
+
463 _data.neighbors = Kokkos::View<int**, memory_space>(
+
464 Kokkos::ViewAllocateWithoutInitializing( "neighbors" ),
+
465 _data.counts.size(), _data.max_n );
+
466 }
+
467 }
+
468
+
469 // Neighbor count team operator.
+
470 struct FillNeighborsTag
+
471 {
+
472 };
+
473 using FillNeighborsPolicy =
+
474 Kokkos::TeamPolicy<execution_space, FillNeighborsTag,
+
475 Kokkos::IndexType<int>,
+
476 Kokkos::Schedule<Kokkos::Dynamic>>;
+
477 KOKKOS_INLINE_FUNCTION
+
478 void
+
479 operator()( const FillNeighborsTag&,
+
480 const typename FillNeighborsPolicy::member_type& team ) const
+
481 {
+
482 // The league rank of the team is the cardinal cell index we are
+
483 // working on.
+
484 int cell = team.league_rank();
+
485
+
486 // Get the stencil for this cell.
+
487 int imin, imax, jmin, jmax, kmin, kmax;
+
488 linked_cell_list.getStencilCells( cell, imin, imax, jmin, jmax, kmin,
+
489 kmax );
+
490
+
491 // Operate on the particles in the bin.
+
492 std::size_t b_offset = bin_data_1d.binOffset( cell );
+
493 Kokkos::parallel_for(
+
494 Kokkos::TeamThreadRange( team, 0, bin_data_1d.binSize( cell ) ),
+
495 [&]( const int bi )
+
496 {
+
497 // Get the true particle id. The binned particle index is the
+
498 // league rank of the team.
+
499 std::size_t pid = linked_cell_list.permutation( bi + b_offset );
+
500
+
501 if ( ( pid >= pid_begin ) && ( pid < pid_end ) )
+
502 {
+
503 // Cache the particle coordinates.
+
504 double x_p = _position( pid, 0 );
+
505 double y_p = _position( pid, 1 );
+
506 double z_p = _position( pid, 2 );
+
507
+
508 // Loop over the cell stencil.
+
509 for ( int i = imin; i < imax; ++i )
+
510 for ( int j = jmin; j < jmax; ++j )
+
511 for ( int k = kmin; k < kmax; ++k )
+
512 {
+
513 // See if we should actually check this box for
+
514 // neighbors.
+
515 if ( linked_cell_list.cellStencil()
+
516 .grid.minDistanceToPoint(
+
517 x_p, y_p, z_p, i, j, k ) <= rsqr )
+
518 {
+
519 // Check the particles in this bin to see if
+
520 // they are neighbors.
+
521 std::size_t n_offset =
+
522 linked_cell_list.binOffset( i, j, k );
+
523 int num_n =
+
524 linked_cell_list.binSize( i, j, k );
+
525 neighbor_for( team, pid, x_p, y_p, z_p,
+
526 n_offset, num_n,
+
527 BuildOpTag() );
+
528 }
+
529 }
+
530 }
+
531 } );
+
532 }
+
533
+
534 // Neighbor fill team vector loop.
+
535 KOKKOS_INLINE_FUNCTION void
+
536 neighbor_for( const typename FillNeighborsPolicy::member_type& team,
+
537 const std::size_t pid, const double x_p, const double y_p,
+
538 const double z_p, const int n_offset, const int num_n,
+
539 TeamVectorOpTag ) const
+
540 {
+
541 Kokkos::parallel_for(
+
542 Kokkos::ThreadVectorRange( team, num_n ), [&]( const int n )
+
543 { neighbor_kernel( pid, x_p, y_p, z_p, n_offset, n ); } );
+
544 }
+
545
+
546 // Neighbor fill serial loop.
+
547 KOKKOS_INLINE_FUNCTION
+
548 void neighbor_for( const typename FillNeighborsPolicy::member_type team,
+
549 const std::size_t pid, const double x_p,
+
550 const double y_p, const double z_p, const int n_offset,
+
551 const int num_n, TeamOpTag ) const
+
552 {
+
553 for ( int n = 0; n < num_n; n++ )
+
554 Kokkos::single(
+
555 Kokkos::PerThread( team ),
+
556 [&]() { neighbor_kernel( pid, x_p, y_p, z_p, n_offset, n ); } );
+
557 }
+
558
+
559 // Neighbor fill kernel.
+
560 KOKKOS_INLINE_FUNCTION
+
561 void neighbor_kernel( const int pid, const double x_p, const double y_p,
+
562 const double z_p, const int n_offset,
+
563 const int n ) const
+
564 {
+
565 // Get the true id of the candidate neighbor.
+
566 std::size_t nid = linked_cell_list.permutation( n_offset + n );
+
567
+
568 // Cache the candidate neighbor particle coordinates.
+
569 double x_n = _position( nid, 0 );
+
570 double y_n = _position( nid, 1 );
+
571 double z_n = _position( nid, 2 );
+
572
+
573 // If this could be a valid neighbor, continue.
+
574 if ( NeighborDiscriminator<AlgorithmTag>::isValid(
+
575 pid, x_p, y_p, z_p, nid, x_n, y_n, z_n ) )
+
576 {
+
577 // Calculate the distance between the particle and its candidate
+
578 // neighbor.
+
579 PositionValueType dx = x_p - x_n;
+
580 PositionValueType dy = y_p - y_n;
+
581 PositionValueType dz = z_p - z_n;
+
582 PositionValueType dist_sqr = dx * dx + dy * dy + dz * dz;
+
583
+
584 // If within the cutoff increment the neighbor count and add as a
+
585 // neighbor at that index.
+
586 if ( dist_sqr <= cutoff( pid ) )
+
587 {
+
588 _data.addNeighbor( pid, nid );
+
589 }
+
590 }
+
591 }
+
592};
+
593
+
594// Builder creation functions. This is only necessary to define the different
+
595// random access types.
+
596template <class DeviceType, class AlgorithmTag, class LayoutTag,
+
597 class BuildOpTag, class PositionType>
+
598auto createVerletListBuilder(
+
599 PositionType x, const std::size_t begin, const std::size_t end,
+
600 const typename PositionType::value_type radius,
+
601 const typename PositionType::value_type cell_size_ratio,
+
602 const typename PositionType::value_type grid_min[3],
+
603 const typename PositionType::value_type grid_max[3],
+
604 const std::size_t max_neigh,
+
605 typename std::enable_if<( is_slice<PositionType>::value ), int>::type* = 0 )
606{
-
607 public:
-
608 static_assert( Kokkos::is_memory_space<MemorySpace>::value, "" );
-
609
-
611 using memory_space = MemorySpace;
-
612
-
614 using execution_space = typename memory_space::execution_space;
-
615
- -
618
- -
623
-
658 template <class PositionType>
-
- -
660 PositionType x, const std::size_t begin, const std::size_t end,
-
661 const typename PositionType::value_type neighborhood_radius,
-
662 const typename PositionType::value_type cell_size_ratio,
-
663 const typename PositionType::value_type grid_min[3],
-
664 const typename PositionType::value_type grid_max[3],
-
665 const std::size_t max_neigh = 0,
-
666 typename std::enable_if<( is_slice<PositionType>::value ||
-
667 Kokkos::is_view<PositionType>::value ),
-
668 int>::type* = 0 )
-
669 {
-
670 build( x, begin, end, neighborhood_radius, cell_size_ratio, grid_min,
-
671 grid_max, max_neigh );
-
672 }
-
-
673
-
678 template <class PositionType>
-
679 void
-
-
680 build( PositionType x, const std::size_t begin, const std::size_t end,
-
681 const typename PositionType::value_type neighborhood_radius,
-
682 const typename PositionType::value_type cell_size_ratio,
-
683 const typename PositionType::value_type grid_min[3],
-
684 const typename PositionType::value_type grid_max[3],
-
685 const std::size_t max_neigh = 0,
-
686 typename std::enable_if<( is_slice<PositionType>::value ||
-
687 Kokkos::is_view<PositionType>::value ),
-
688 int>::type* = 0 )
-
689 {
-
690 // Use the default execution space.
-
691 build( execution_space{}, x, begin, end, neighborhood_radius,
-
692 cell_size_ratio, grid_min, grid_max, max_neigh );
-
693 }
-
-
698 template <class PositionType, class ExecutionSpace>
-
699 void
-
-
700 build( ExecutionSpace, PositionType x, const std::size_t begin,
-
701 const std::size_t end,
-
702 const typename PositionType::value_type neighborhood_radius,
-
703 const typename PositionType::value_type cell_size_ratio,
-
704 const typename PositionType::value_type grid_min[3],
-
705 const typename PositionType::value_type grid_max[3],
-
706 const std::size_t max_neigh = 0,
-
707 typename std::enable_if<( is_slice<PositionType>::value ||
-
708 Kokkos::is_view<PositionType>::value ),
-
709 int>::type* = 0 )
-
710 {
-
711 Kokkos::Profiling::ScopedRegion region( "Cabana::VerletList::build" );
-
712
- +
607 using RandomAccessPositionType = typename PositionType::random_access_slice;
+
608 return VerletListBuilder<DeviceType, RandomAccessPositionType,
+
609 typename PositionType::value_type, AlgorithmTag,
+
610 LayoutTag, BuildOpTag>(
+
611 x, begin, end, radius, cell_size_ratio, grid_min, grid_max, max_neigh );
+
612}
+
613
+
614template <class DeviceType, class AlgorithmTag, class LayoutTag,
+
615 class BuildOpTag, class PositionType>
+
616auto createVerletListBuilder(
+
617 PositionType x, const std::size_t begin, const std::size_t end,
+
618 const typename PositionType::value_type radius,
+
619 const typename PositionType::value_type cell_size_ratio,
+
620 const typename PositionType::value_type grid_min[3],
+
621 const typename PositionType::value_type grid_max[3],
+
622 const std::size_t max_neigh,
+
623 typename std::enable_if<( Kokkos::is_view<PositionType>::value ),
+
624 int>::type* = 0 )
+
625{
+
626 using RandomAccessPositionType =
+
627 Kokkos::View<typename PositionType::value_type**, DeviceType,
+
628 Kokkos::MemoryTraits<Kokkos::RandomAccess>>;
+
629 return VerletListBuilder<DeviceType, RandomAccessPositionType,
+
630 typename PositionType::value_type, AlgorithmTag,
+
631 LayoutTag, BuildOpTag>(
+
632 x, begin, end, radius, cell_size_ratio, grid_min, grid_max, max_neigh );
+
633}
+
634
+
635template <class DeviceType, class AlgorithmTag, class LayoutTag,
+
636 class BuildOpTag, class PositionType, class RadiusType>
+
637auto createVerletListBuilder(
+
638 PositionType x, const std::size_t begin, const std::size_t end,
+
639 const typename PositionType::value_type background_radius,
+
640 const RadiusType radius,
+
641 const typename PositionType::value_type cell_size_ratio,
+
642 const typename PositionType::value_type grid_min[3],
+
643 const typename PositionType::value_type grid_max[3],
+
644 const std::size_t max_neigh,
+
645 typename std::enable_if<( is_slice<PositionType>::value ), int>::type* = 0 )
+
646{
+
647 using RandomAccessPositionType = typename PositionType::random_access_slice;
+
648 return VerletListBuilder<DeviceType, RandomAccessPositionType, RadiusType,
+
649 AlgorithmTag, LayoutTag, BuildOpTag>(
+
650 x, begin, end, background_radius, radius, cell_size_ratio, grid_min,
+
651 grid_max, max_neigh );
+
652}
+
653
+
654template <class DeviceType, class AlgorithmTag, class LayoutTag,
+
655 class BuildOpTag, class PositionType, class RadiusType>
+
656auto createVerletListBuilder(
+
657 PositionType x, const std::size_t begin, const std::size_t end,
+
658 const typename PositionType::value_type background_radius,
+
659 const RadiusType radius,
+
660 const typename PositionType::value_type cell_size_ratio,
+
661 const typename PositionType::value_type grid_min[3],
+
662 const typename PositionType::value_type grid_max[3],
+
663 const std::size_t max_neigh,
+
664 typename std::enable_if<( Kokkos::is_view<PositionType>::value ),
+
665 int>::type* = 0 )
+
666{
+
667 using RandomAccessPositionType =
+
668 Kokkos::View<typename PositionType::value_type**, DeviceType,
+
669 Kokkos::MemoryTraits<Kokkos::RandomAccess>>;
+
670 return VerletListBuilder<DeviceType, RandomAccessPositionType, RadiusType,
+
671 AlgorithmTag, LayoutTag, BuildOpTag>(
+
672 x, begin, end, background_radius, radius, cell_size_ratio, grid_min,
+
673 grid_max, max_neigh );
+
674}
+
675
+
676//---------------------------------------------------------------------------//
+
677
+
679} // end namespace Impl
+
680
+
681//---------------------------------------------------------------------------//
+
699template <class MemorySpace, class AlgorithmTag, class LayoutTag,
+
700 class BuildTag = TeamVectorOpTag>
+
+ +
702{
+
703 public:
+
704 static_assert( Kokkos::is_memory_space<MemorySpace>::value, "" );
+
705
+
707 using memory_space = MemorySpace;
+
708
+
710 using execution_space = typename memory_space::execution_space;
+
711
+
714
-
715 assert( end >= begin );
-
716 assert( end <= size( x ) );
-
717
-
718 using device_type = Kokkos::Device<ExecutionSpace, memory_space>;
+
719
-
720 // Create a builder functor.
-
721 auto builder =
-
722 Impl::createVerletListBuilder<device_type, PositionType,
-
723 AlgorithmTag, LayoutTag, BuildTag>(
-
724 x, begin, end, neighborhood_radius, cell_size_ratio, grid_min,
-
725 grid_max, max_neigh );
-
726
-
727 // For each particle in the range check each neighboring bin for
-
728 // neighbor particles. Bins are at least the size of the neighborhood
-
729 // radius so the bin in which the particle resides and any surrounding
-
730 // bins are guaranteed to contain the neighboring particles.
-
731 // For CSR lists, we count, then fill neighbors. For 2D lists, we
-
732 // count and fill at the same time, unless the array size is exceeded,
-
733 // at which point only counting is continued to reallocate and refill.
-
734 typename decltype( builder )::FillNeighborsPolicy fill_policy(
-
735 builder.bin_data_1d.numBin(), Kokkos::AUTO, 4 );
-
736 if ( builder.count )
-
737 {
-
738 typename decltype( builder )::CountNeighborsPolicy count_policy(
-
739 builder.bin_data_1d.numBin(), Kokkos::AUTO, 4 );
-
740 Kokkos::parallel_for( "Cabana::VerletList::count_neighbors",
-
741 count_policy, builder );
-
742 }
-
743 else
-
744 {
-
745 builder.processCounts( LayoutTag() );
-
746 Kokkos::parallel_for( "Cabana::VerletList::fill_neighbors",
-
747 fill_policy, builder );
-
748 }
-
749 Kokkos::fence();
-
750
-
751 // Process the counts by computing offsets and allocating the neighbor
-
752 // list, if needed.
-
753 builder.processCounts( LayoutTag() );
-
754
-
755 // For each particle in the range fill (or refill) its part of the
-
756 // neighbor list.
-
757 if ( builder.count or builder.refill )
-
758 {
-
759 Kokkos::parallel_for( "Cabana::VerletList::fill_neighbors",
-
760 fill_policy, builder );
-
761 Kokkos::fence();
-
762 }
-
763
-
764 // Get the data from the builder.
-
765 _data = builder._data;
-
766 }
-
-
767
-
769 KOKKOS_INLINE_FUNCTION
-
-
770 void setNeighbor( const std::size_t particle_index,
-
771 const std::size_t neighbor_index,
-
772 const int new_index ) const
-
773 {
-
774 _data.setNeighbor( particle_index, neighbor_index, new_index );
-
775 }
-
-
776};
-
-
777
-
778//---------------------------------------------------------------------------//
-
779// Neighbor list interface implementation.
-
780//---------------------------------------------------------------------------//
-
782template <class MemorySpace, class AlgorithmTag, class BuildTag>
-
- -
784 VerletList<MemorySpace, AlgorithmTag, VerletLayoutCSR, BuildTag>>
-
785{
-
786 public:
-
788 using memory_space = MemorySpace;
-
790 using list_type =
- -
792
-
794 KOKKOS_INLINE_FUNCTION
-
-
795 static std::size_t totalNeighbor( const list_type& list )
-
796 {
-
797 // Size of the allocated memory gives total neighbors.
-
798 return list._data.neighbors.extent( 0 );
-
799 }
-
-
800
-
802 KOKKOS_INLINE_FUNCTION
-
-
803 static std::size_t maxNeighbor( const list_type& list )
-
804 {
-
805 std::size_t num_p = list._data.counts.size();
-
806 return Impl::maxNeighbor( list, num_p );
-
807 }
-
-
808
-
810 KOKKOS_INLINE_FUNCTION
-
-
811 static std::size_t numNeighbor( const list_type& list,
-
812 const std::size_t particle_index )
-
813 {
-
814 return list._data.counts( particle_index );
-
815 }
-
-
816
-
819 KOKKOS_INLINE_FUNCTION
-
-
820 static std::size_t getNeighbor( const list_type& list,
-
821 const std::size_t particle_index,
-
822 const std::size_t neighbor_index )
-
823 {
-
824 return list._data.neighbors( list._data.offsets( particle_index ) +
-
825 neighbor_index );
-
826 }
-
-
827};
-
-
828
-
829//---------------------------------------------------------------------------//
-
831template <class MemorySpace, class AlgorithmTag, class BuildTag>
-
- -
833 VerletList<MemorySpace, AlgorithmTag, VerletLayout2D, BuildTag>>
-
834{
-
835 public:
-
837 using memory_space = MemorySpace;
-
839 using list_type =
- -
841
-
843 KOKKOS_INLINE_FUNCTION
-
-
844 static std::size_t totalNeighbor( const list_type& list )
-
845 {
-
846 std::size_t num_p = list._data.counts.size();
-
847 return Impl::totalNeighbor( list, num_p );
-
848 }
-
-
849
-
851 KOKKOS_INLINE_FUNCTION
-
-
852 static std::size_t maxNeighbor( const list_type& list )
-
853 {
-
854 // Stored during neighbor search.
-
855 return list._data.max_n;
-
856 }
-
-
857
-
859 KOKKOS_INLINE_FUNCTION
-
-
860 static std::size_t numNeighbor( const list_type& list,
-
861 const std::size_t particle_index )
-
862 {
-
863 return list._data.counts( particle_index );
-
864 }
-
-
865
-
868 KOKKOS_INLINE_FUNCTION
-
-
869 static std::size_t getNeighbor( const list_type& list,
-
870 const std::size_t particle_index,
-
871 const std::size_t neighbor_index )
-
872 {
-
873 return list._data.neighbors( particle_index, neighbor_index );
-
874 }
-
-
875};
-
-
876
-
877//---------------------------------------------------------------------------//
-
878
-
879} // end namespace Cabana
-
880
-
881#endif // end CABANA_VERLETLIST_HPP
+
754 template <class PositionType>
+
+ +
756 PositionType x, const std::size_t begin, const std::size_t end,
+
757 const typename PositionType::value_type neighborhood_radius,
+
758 const typename PositionType::value_type cell_size_ratio,
+
759 const typename PositionType::value_type grid_min[3],
+
760 const typename PositionType::value_type grid_max[3],
+
761 const std::size_t max_neigh = 0,
+
762 typename std::enable_if<( is_slice<PositionType>::value ||
+
763 Kokkos::is_view<PositionType>::value ),
+
764 int>::type* = 0 )
+
765 {
+
766 build( x, begin, end, neighborhood_radius, cell_size_ratio, grid_min,
+
767 grid_max, max_neigh );
+
768 }
+
+
769
+
806 template <class PositionSlice, class RadiusSlice>
+
+
807 VerletList( PositionSlice x, const std::size_t begin, const std::size_t end,
+
808 const typename PositionSlice::value_type background_radius,
+
809 RadiusSlice neighborhood_radius,
+
810 const typename PositionSlice::value_type cell_size_ratio,
+
811 const typename PositionSlice::value_type grid_min[3],
+
812 const typename PositionSlice::value_type grid_max[3],
+
813 const std::size_t max_neigh = 0,
+
814 typename std::enable_if<( is_slice<PositionSlice>::value ),
+
815 int>::type* = 0 )
+
816 {
+
817 build( x, begin, end, background_radius, neighborhood_radius,
+
818 cell_size_ratio, grid_min, grid_max, max_neigh );
+
819 }
+
+
820
+
825 template <class PositionType>
+
826 void
+
+
827 build( PositionType x, const std::size_t begin, const std::size_t end,
+
828 const typename PositionType::value_type neighborhood_radius,
+
829 const typename PositionType::value_type cell_size_ratio,
+
830 const typename PositionType::value_type grid_min[3],
+
831 const typename PositionType::value_type grid_max[3],
+
832 const std::size_t max_neigh = 0,
+
833 typename std::enable_if<( is_slice<PositionType>::value ||
+
834 Kokkos::is_view<PositionType>::value ),
+
835 int>::type* = 0 )
+
836 {
+
837 // Use the default execution space.
+
838 build( execution_space{}, x, begin, end, neighborhood_radius,
+
839 cell_size_ratio, grid_min, grid_max, max_neigh );
+
840 }
+
+
845 template <class PositionType, class ExecutionSpace>
+
846 void
+
+
847 build( ExecutionSpace, PositionType x, const std::size_t begin,
+
848 const std::size_t end,
+
849 const typename PositionType::value_type neighborhood_radius,
+
850 const typename PositionType::value_type cell_size_ratio,
+
851 const typename PositionType::value_type grid_min[3],
+
852 const typename PositionType::value_type grid_max[3],
+
853 const std::size_t max_neigh = 0,
+
854 typename std::enable_if<( is_slice<PositionType>::value ||
+
855 Kokkos::is_view<PositionType>::value ),
+
856 int>::type* = 0 )
+
857 {
+
858 Kokkos::Profiling::ScopedRegion region( "Cabana::VerletList::build" );
+
859
+ +
861
+
862 assert( end >= begin );
+
863 assert( end <= size( x ) );
+
864
+
865 using device_type = Kokkos::Device<ExecutionSpace, memory_space>;
+
866 // Create a builder functor.
+
867 auto builder = Impl::createVerletListBuilder<device_type, AlgorithmTag,
+
868 LayoutTag, BuildTag>(
+
869 x, begin, end, neighborhood_radius, cell_size_ratio, grid_min,
+
870 grid_max, max_neigh );
+
871 buildImpl( builder );
+
872 }
+
+
873
+
878 template <class PositionSlice, class RadiusSlice>
+
+
879 void build( PositionSlice x, const std::size_t begin, const std::size_t end,
+
880 const typename PositionSlice::value_type background_radius,
+
881 RadiusSlice neighborhood_radius,
+
882 const typename PositionSlice::value_type cell_size_ratio,
+
883 const typename PositionSlice::value_type grid_min[3],
+
884 const typename PositionSlice::value_type grid_max[3],
+
885 const std::size_t max_neigh = 0 )
+
886 {
+
887 // Use the default execution space.
+
888 build( execution_space{}, x, begin, end, background_radius,
+
889 neighborhood_radius, cell_size_ratio, grid_min, grid_max,
+
890 max_neigh );
+
891 }
+
+
896 template <class PositionSlice, class RadiusSlice, class ExecutionSpace>
+
+
897 void build( ExecutionSpace, PositionSlice x, const std::size_t begin,
+
898 const std::size_t end,
+
899 const typename PositionSlice::value_type background_radius,
+
900 RadiusSlice neighborhood_radius,
+
901 const typename PositionSlice::value_type cell_size_ratio,
+
902 const typename PositionSlice::value_type grid_min[3],
+
903 const typename PositionSlice::value_type grid_max[3],
+
904 const std::size_t max_neigh = 0 )
+
905 {
+
906 Kokkos::Profiling::ScopedRegion region( "Cabana::VerletList::build" );
+
907
+ +
909
+
910 assert( end >= begin );
+
911 assert( end <= x.size() );
+
912
+
913 // Create a builder functor.
+
914 using device_type = Kokkos::Device<ExecutionSpace, memory_space>;
+
915 auto builder = Impl::createVerletListBuilder<device_type, AlgorithmTag,
+
916 LayoutTag, BuildTag>(
+
917 x, begin, end, background_radius, neighborhood_radius,
+
918 cell_size_ratio, grid_min, grid_max, max_neigh );
+
919 buildImpl( builder );
+
920 }
+
+
921
+
923 template <class BuilderType>
+
924 void buildImpl( BuilderType builder )
+
925 {
+
926 // For each particle in the range check each neighboring bin for
+
927 // neighbor particles. Bins are at least the size of the
+
928 // neighborhood radius so the bin in which the particle resides and
+
929 // any surrounding bins are guaranteed to contain the neighboring
+
930 // particles. For CSR lists, we count, then fill neighbors. For 2D
+
931 // lists, we count and fill at the same time, unless the array size
+
932 // is exceeded, at which point only counting is continued to
+
933 // reallocate and refill.
+
934 typename BuilderType::FillNeighborsPolicy fill_policy(
+
935 builder.bin_data_1d.numBin(), Kokkos::AUTO, 4 );
+
936 if ( builder.count )
+
937 {
+
938 typename BuilderType::CountNeighborsPolicy count_policy(
+
939 builder.bin_data_1d.numBin(), Kokkos::AUTO, 4 );
+
940 Kokkos::parallel_for( "Cabana::VerletList::count_neighbors",
+
941 count_policy, builder );
+
942 }
+
943 else
+
944 {
+
945 builder.processCounts( LayoutTag() );
+
946 Kokkos::parallel_for( "Cabana::VerletList::fill_neighbors",
+
947 fill_policy, builder );
+
948 }
+
949 Kokkos::fence();
+
950
+
951 // Process the counts by computing offsets and allocating the neighbor
+
952 // list, if needed.
+
953 builder.processCounts( LayoutTag() );
+
954
+
955 // For each particle in the range fill (or refill) its part of the
+
956 // neighbor list.
+
957 if ( builder.count or builder.refill )
+
958 {
+
959 Kokkos::parallel_for( "Cabana::VerletList::fill_neighbors",
+
960 fill_policy, builder );
+
961 Kokkos::fence();
+
962 }
+
963
+
964 // Get the data from the builder.
+
965 _data = builder._data;
+
966 }
+
968
+
970 KOKKOS_INLINE_FUNCTION
+
+
971 void setNeighbor( const std::size_t particle_index,
+
972 const std::size_t neighbor_index,
+
973 const int new_index ) const
+
974 {
+
975 _data.setNeighbor( particle_index, neighbor_index, new_index );
+
976 }
+
+
977};
+
+
978
+
979//---------------------------------------------------------------------------//
+
980// Neighbor list interface implementation.
+
981//---------------------------------------------------------------------------//
+
983template <class MemorySpace, class AlgorithmTag, class BuildTag>
+
+ +
985 VerletList<MemorySpace, AlgorithmTag, VerletLayoutCSR, BuildTag>>
+
986{
+
987 public:
+
989 using memory_space = MemorySpace;
+
991 using list_type =
+ +
993
+
995 KOKKOS_INLINE_FUNCTION
+
+
996 static std::size_t totalNeighbor( const list_type& list )
+
997 {
+
998 // Size of the allocated memory gives total neighbors.
+
999 return list._data.neighbors.extent( 0 );
+
1000 }
+
+
1001
+
1003 KOKKOS_INLINE_FUNCTION
+
+
1004 static std::size_t maxNeighbor( const list_type& list )
+
1005 {
+
1006 std::size_t num_p = list._data.counts.size();
+
1007 return Impl::maxNeighbor( list, num_p );
+
1008 }
+
+
1009
+
1011 KOKKOS_INLINE_FUNCTION
+
+
1012 static std::size_t numNeighbor( const list_type& list,
+
1013 const std::size_t particle_index )
+
1014 {
+
1015 return list._data.counts( particle_index );
+
1016 }
+
+
1017
+
1020 KOKKOS_INLINE_FUNCTION
+
+
1021 static std::size_t getNeighbor( const list_type& list,
+
1022 const std::size_t particle_index,
+
1023 const std::size_t neighbor_index )
+
1024 {
+
1025 return list._data.neighbors( list._data.offsets( particle_index ) +
+
1026 neighbor_index );
+
1027 }
+
+
1028};
+
+
1029
+
1030//---------------------------------------------------------------------------//
+
1032template <class MemorySpace, class AlgorithmTag, class BuildTag>
+
+ +
1034 VerletList<MemorySpace, AlgorithmTag, VerletLayout2D, BuildTag>>
+
1035{
+
1036 public:
+
1038 using memory_space = MemorySpace;
+ + +
1042
+
1044 KOKKOS_INLINE_FUNCTION
+
+
1045 static std::size_t totalNeighbor( const list_type& list )
+
1046 {
+
1047 std::size_t num_p = list._data.counts.size();
+
1048 return Impl::totalNeighbor( list, num_p );
+
1049 }
+
+
1050
+
1052 KOKKOS_INLINE_FUNCTION
+
+
1053 static std::size_t maxNeighbor( const list_type& list )
+
1054 {
+
1055 // Stored during neighbor search.
+
1056 return list._data.max_n;
+
1057 }
+
+
1058
+
1060 KOKKOS_INLINE_FUNCTION
+
+
1061 static std::size_t numNeighbor( const list_type& list,
+
1062 const std::size_t particle_index )
+
1063 {
+
1064 return list._data.counts( particle_index );
+
1065 }
+
+
1066
+
1069 KOKKOS_INLINE_FUNCTION
+
+
1070 static std::size_t getNeighbor( const list_type& list,
+
1071 const std::size_t particle_index,
+
1072 const std::size_t neighbor_index )
+
1073 {
+
1074 return list._data.neighbors( particle_index, neighbor_index );
+
1075 }
+
+
1076};
+
+
1077
+
1078//---------------------------------------------------------------------------//
+
1079
+
1080} // end namespace Cabana
+
1081
+
1082#endif // end CABANA_VERLETLIST_HPP
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:595
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.
Neighbor list interface.
SIMD and neighbor extension of Kokkos parallel iteration.
-
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:869
-
MemorySpace memory_space
Kokkos memory space.
Definition Cabana_VerletList.hpp:837
-
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:860
-
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:844
-
static KOKKOS_INLINE_FUNCTION std::size_t maxNeighbor(const list_type &list)
Get the maximum number of neighbors per particle.
Definition Cabana_VerletList.hpp:852
-
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:811
-
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:803
-
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:795
-
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:820
-
MemorySpace memory_space
Kokkos memory space.
Definition Cabana_VerletList.hpp:788
+
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:1070
+
MemorySpace memory_space
Kokkos memory space.
Definition Cabana_VerletList.hpp:1038
+
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:1061
+
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:1045
+
static KOKKOS_INLINE_FUNCTION std::size_t maxNeighbor(const list_type &list)
Get the maximum number of neighbors per particle.
Definition Cabana_VerletList.hpp:1053
+
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:1012
+
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:1004
+
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:996
+
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:1021
+
MemorySpace memory_space
Kokkos memory space.
Definition Cabana_VerletList.hpp:989
Neighbor list interface. Provides an interface callable at the functor level that gives access to nei...
Definition Cabana_NeighborList.hpp:114
-
Neighbor list implementation based on binning particles on a 3d Cartesian grid with cells of the same...
Definition Cabana_VerletList.hpp:606
-
VerletListData< memory_space, LayoutTag > _data
Verlet list data.
Definition Cabana_VerletList.hpp:617
-
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:659
-
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:770
-
typename memory_space::execution_space execution_space
Kokkos default execution space for this memory space.
Definition Cabana_VerletList.hpp:614
-
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:700
-
MemorySpace memory_space
Kokkos memory space in which the neighbor list data resides.
Definition Cabana_VerletList.hpp:611
-
VerletList()
Default constructor.
Definition Cabana_VerletList.hpp:622
-
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)
Given a list of particle positions and a neighborhood radius calculate the neighbor list.
Definition Cabana_VerletList.hpp:680
+
Neighbor list implementation based on binning particles on a 3d Cartesian grid with cells of the same...
Definition Cabana_VerletList.hpp:702
+
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:879
+
VerletListData< memory_space, LayoutTag > _data
Verlet list data.
Definition Cabana_VerletList.hpp:713
+
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:755
+
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:971
+
typename memory_space::execution_space execution_space
Kokkos default execution space for this memory space.
Definition Cabana_VerletList.hpp:710
+
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:847
+
MemorySpace memory_space
Kokkos memory space in which the neighbor list data resides.
Definition Cabana_VerletList.hpp:707
+
VerletList()
Default constructor.
Definition Cabana_VerletList.hpp:718
+
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:897
+
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:807
+
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)
Given a list of particle positions and a neighborhood radius calculate the neighbor list.
Definition Cabana_VerletList.hpp:827
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
diff --git a/doxygen/classCabana_1_1VerletList-members.html b/doxygen/classCabana_1_1VerletList-members.html index 30769bd19..25c27314c 100644 --- a/doxygen/classCabana_1_1VerletList-members.html +++ b/doxygen/classCabana_1_1VerletList-members.html @@ -97,11 +97,14 @@ _dataCabana::VerletList< MemorySpace, AlgorithmTag, LayoutTag, BuildTag > 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)Cabana::VerletList< MemorySpace, AlgorithmTag, LayoutTag, BuildTag >inline 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)Cabana::VerletList< MemorySpace, AlgorithmTag, LayoutTag, BuildTag >inline + 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)Cabana::VerletList< MemorySpace, AlgorithmTag, LayoutTag, BuildTag >inline + 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)Cabana::VerletList< MemorySpace, AlgorithmTag, LayoutTag, BuildTag >inline execution_space typedefCabana::VerletList< MemorySpace, AlgorithmTag, LayoutTag, BuildTag > memory_space typedefCabana::VerletList< MemorySpace, AlgorithmTag, LayoutTag, BuildTag > setNeighbor(const std::size_t particle_index, const std::size_t neighbor_index, const int new_index) constCabana::VerletList< MemorySpace, AlgorithmTag, LayoutTag, BuildTag >inline VerletList()Cabana::VerletList< MemorySpace, AlgorithmTag, LayoutTag, BuildTag >inline 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)Cabana::VerletList< MemorySpace, AlgorithmTag, LayoutTag, BuildTag >inline + 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)Cabana::VerletList< MemorySpace, AlgorithmTag, LayoutTag, BuildTag >inline