12#ifndef CABANA_GRID_LOCALGRID_SPARSE_IMPL_HPP
13#define CABANA_GRID_LOCALGRID_SPARSE_IMPL_HPP
24template <
class Scalar, std::
size_t NumSpaceDim>
27 const int halo_cell_width,
const long cell_num_per_tile_dim )
28 : _global_grid( global_grid )
29 , _cell_num_per_tile_dim( cell_num_per_tile_dim )
31 static_assert( 3 ==
num_space_dim,
"SparseMesh supports only 3D" );
34 static_cast<int>( ( halo_cell_width + cell_num_per_tile_dim - 1 ) /
35 cell_num_per_tile_dim ) *
36 cell_num_per_tile_dim;
41template <
class Scalar, std::
size_t NumSpaceDim>
50template <
class Scalar, std::
size_t NumSpaceDim>
59template <
class Scalar, std::
size_t NumSpaceDim>
62 return _halo_cell_width;
67template <
class Scalar, std::
size_t NumSpaceDim>
70 return _halo_cell_width / _cell_num_per_tile_dim;
75template <
class Scalar, std::
size_t NumSpaceDim>
79 return _global_grid->ownedNumCell( d ) + 2 * _halo_cell_width;
84template <
class Scalar, std::
size_t NumSpaceDim>
87 int total_num_cell = 1;
91 return total_num_cell;
97template <
class Scalar, std::
size_t NumSpaceDim>
99 const std::array<int, num_space_dim>& off_ijk )
const
101 std::array<int, num_space_dim> nijk;
103 nijk[d] = _global_grid->dimBlockId( d ) + off_ijk[d];
104 return _global_grid->blockRank( nijk );
107template <
class Scalar, std::
size_t NumSpaceDim>
109 const int off_i,
const int off_j,
const int off_k )
const
111 std::array<int, num_space_dim> off_ijk = { off_i, off_j, off_k };
119template <
class Scalar, std::
size_t NumSpaceDim>
120template <
class DecompositionTag,
class EntityType,
class IndexType>
122 DecompositionTag t1, EntityType t2, IndexType t3 )
const
125 return indexSpaceImpl( t1, t2, t3 );
135template <
class Scalar, std::
size_t NumSpaceDim>
136template <
unsigned long long cellBitsPerTileDim,
class DecompositionTag,
139 DecompositionTag t1, EntityType t2,
140 const std::array<int, num_space_dim>& off_ijk,
const int halo_width )
const
143 static constexpr unsigned long long cell_num_per_tile_dim =
144 1 << cellBitsPerTileDim;
146 int hw = ( -1 == halo_width ) ? _halo_cell_width : halo_width;
147 hw =
static_cast<int>( ( hw + cell_num_per_tile_dim - 1 ) /
148 cell_num_per_tile_dim ) *
149 cell_num_per_tile_dim;
152 for ( std::size_t d = 0; d < num_space_dim; ++d )
153 if ( off_ijk[d] < -1 || 1 < off_ijk[d] )
154 throw std::logic_error(
"Neighbor indices out of bounds" );
157 if ( hw > _halo_cell_width )
158 throw std::logic_error(
159 "Requested halo width larger than local grid halo" );
163 if ( neighborRank( off_ijk ) < 0 )
165 std::array<long, num_space_dim> zero_size;
166 for ( std::size_t d = 0; d < num_space_dim; ++d )
173 return sharedTileIndexSpaceImpl<cellBitsPerTileDim>( t1, t2, off_ijk, hw );
178template <
class Scalar, std::
size_t NumSpaceDim>
179template <
unsigned long long cellBitsPerTileDim,
class DecompositionTag,
180 class EntityType, std::size_t NSD>
181std::enable_if_t<3 == NSD, TileIndexSpace<3, cellBitsPerTileDim>>
182LocalGrid<SparseMesh<Scalar, NumSpaceDim>>::sharedTileIndexSpace(
183 DecompositionTag t1, EntityType t2,
const int off_i,
const int off_j,
184 const int off_k,
const int halo_width )
const
186 std::array<int, 3> off_ijk = { off_i, off_j, off_k };
187 return sharedTileIndexSpace<cellBitsPerTileDim>( t1, t2, off_ijk,
195template <
class Scalar, std::
size_t NumSpaceDim>
198 -> IndexSpace<num_space_dim>
201 std::array<long, num_space_dim> min;
202 for ( std::size_t d = 0; d < num_space_dim; ++d )
203 min[d] = _halo_cell_width;
206 std::array<long, num_space_dim> max;
207 for ( std::size_t d = 0; d < num_space_dim; ++d )
208 max[d] = min[d] + _global_grid->ownedNumCell( d );
210 return IndexSpace<num_space_dim>( min, max );
216template <
class Scalar, std::
size_t NumSpaceDim>
219 -> IndexSpace<num_space_dim>
222 std::array<long, num_space_dim>
size;
223 for ( std::size_t d = 0; d < num_space_dim; ++d )
225 size[d] = totalNumCell( d );
228 return IndexSpace<num_space_dim>(
size );
233template <
class Scalar, std::
size_t NumSpaceDim>
236 -> IndexSpace<num_space_dim>
239 std::array<long, num_space_dim> min;
240 for ( std::size_t d = 0; d < num_space_dim; ++d )
241 min[d] = _global_grid->globalOffset( d );
244 std::array<long, num_space_dim> max;
245 for ( std::size_t d = 0; d < num_space_dim; ++d )
246 max[d] = min[d] + _global_grid->ownedNumCell( d );
248 return IndexSpace<num_space_dim>( min, max );
254template <
class Scalar, std::
size_t NumSpaceDim>
255template <
unsigned long long cellBitsPerTileDim>
257 Own,
const std::array<int, num_space_dim>& off_ijk,
258 const int halo_width )
const
259 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
261 auto owned_cell_space = indexSpaceImpl( Own(), Node(), Global() );
263 std::array<long, num_space_dim> min;
264 for ( std::size_t d = 0; d < num_space_dim; ++d )
267 if ( -1 == off_ijk[d] )
268 min[d] = owned_cell_space.min( d ) >> cellBitsPerTileDim;
271 else if ( 0 == off_ijk[d] )
272 min[d] = owned_cell_space.min( d ) >> cellBitsPerTileDim;
275 else if ( 1 == off_ijk[d] )
276 min[d] = ( owned_cell_space.max( d ) - halo_width ) >>
279 throw std::runtime_error(
"Neighbor offset must be 1, 0, or -1" );
283 std::array<long, num_space_dim> max;
284 for ( std::size_t d = 0; d < num_space_dim; ++d )
287 if ( -1 == off_ijk[d] )
288 max[d] = ( owned_cell_space.min( d ) + halo_width ) >>
292 else if ( 0 == off_ijk[d] )
293 max[d] = owned_cell_space.max( d ) >> cellBitsPerTileDim;
296 else if ( 1 == off_ijk[d] )
297 max[d] = owned_cell_space.max( d ) >> cellBitsPerTileDim;
299 throw std::runtime_error(
"Neighbor offset must be 1, 0, or -1" );
302 return TileIndexSpace<num_space_dim, cellBitsPerTileDim>( min, max );
308template <
class Scalar, std::
size_t NumSpaceDim>
309template <
unsigned long long cellBitsPerTileDim>
311 Ghost,
const std::array<int, num_space_dim>& off_ijk,
312 const int halo_width )
const
313 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
316 auto owned_cell_space = indexSpaceImpl( Own(), Node(), Global() );
319 std::array<long, num_space_dim> min;
320 for ( std::size_t d = 0; d < num_space_dim; ++d )
323 if ( -1 == off_ijk[d] )
324 min[d] = ( owned_cell_space.min( d ) - halo_width ) >>
328 else if ( 0 == off_ijk[d] )
329 min[d] = owned_cell_space.min( d ) >> cellBitsPerTileDim;
332 else if ( 1 == off_ijk[d] )
333 min[d] = owned_cell_space.max( d ) >> cellBitsPerTileDim;
335 throw std::runtime_error(
"Neighbor offset must be 1, 0, or -1" );
339 std::array<long, num_space_dim> max;
340 for ( std::size_t d = 0; d < num_space_dim; ++d )
343 if ( -1 == off_ijk[d] )
344 max[d] = owned_cell_space.min( d ) >> cellBitsPerTileDim;
347 else if ( 0 == off_ijk[d] )
348 max[d] = owned_cell_space.max( d ) >> cellBitsPerTileDim;
351 else if ( 1 == off_ijk[d] )
352 max[d] = ( owned_cell_space.max( d ) + halo_width ) >>
355 throw std::runtime_error(
"Neighbor offset must be 1, 0, or -1" );
358 return TileIndexSpace<num_space_dim, cellBitsPerTileDim>( min, max );
365template <
class Scalar, std::
size_t NumSpaceDim>
366template <
class DecompositionTag,
class IndexType>
368 DecompositionTag t1, Node, IndexType t3 )
const -> IndexSpace<num_space_dim>
370 return indexSpaceImpl( t1, t3 );
374template <
class Scalar, std::
size_t NumSpaceDim>
375template <
unsigned long long cellBitsPerTileDim,
class DecompositionTag>
377 DecompositionTag t1, Node,
const std::array<int, num_space_dim>& off_ijk,
378 const int halo_width )
const
379 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
381 return sharedTileIndexSpaceImpl<cellBitsPerTileDim>( t1, off_ijk,
389template <
class Scalar, std::
size_t NumSpaceDim>
390template <
class DecompositionTag,
class IndexType>
392 DecompositionTag t1, Cell, IndexType t3 )
const -> IndexSpace<num_space_dim>
394 return indexSpaceImpl( t1, t3 );
398template <
class Scalar, std::
size_t NumSpaceDim>
399template <
unsigned long long cellBitsPerTileDim,
class DecompositionTag>
401 DecompositionTag t1, Cell,
const std::array<int, num_space_dim>& off_ijk,
402 const int halo_width )
const
403 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
405 return sharedTileIndexSpaceImpl<cellBitsPerTileDim>( t1, off_ijk,
413template <
class Scalar, std::
size_t NumSpaceDim>
414template <
class DecompositionTag,
class IndexType>
416 DecompositionTag t1, Face<Dim::I>, IndexType t3 )
const
417 -> IndexSpace<num_space_dim>
420 "Sparse grid implementation doesn't support Face entities so far" );
421 return indexSpaceImpl( t1, t3 );
425template <
class Scalar, std::
size_t NumSpaceDim>
426template <
class DecompositionTag,
class IndexType>
428 DecompositionTag t1, Face<Dim::J>, IndexType t3 )
const
429 -> IndexSpace<num_space_dim>
432 "Sparse grid implementation doesn't support Face entities so far" );
433 return indexSpaceImpl( t1, t3 );
437template <
class Scalar, std::
size_t NumSpaceDim>
438template <
class DecompositionTag,
class IndexType>
440 DecompositionTag t1, Face<Dim::K>, IndexType t3 )
const
441 -> IndexSpace<num_space_dim>
444 "Sparse grid implementation doesn't support Face entities so far" );
445 return indexSpaceImpl( t1, t3 );
449template <
class Scalar, std::
size_t NumSpaceDim>
450template <
unsigned long long cellBitsPerTileDim,
class DecompositionTag>
452 DecompositionTag t1, Face<Dim::I>,
453 const std::array<int, num_space_dim>& off_ijk,
const int halo_width )
const
454 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
457 "Sparse grid implementation doesn't support Face entities so far" );
458 return sharedTileIndexSpaceImpl<cellBitsPerTileDim>( t1, off_ijk,
463template <
class Scalar, std::
size_t NumSpaceDim>
464template <
unsigned long long cellBitsPerTileDim,
class DecompositionTag>
466 DecompositionTag t1, Face<Dim::J>,
467 const std::array<int, num_space_dim>& off_ijk,
const int halo_width )
const
468 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
471 "Sparse grid implementation doesn't support Face entities so far" );
472 return sharedTileIndexSpaceImpl<cellBitsPerTileDim>( t1, off_ijk,
476template <
class Scalar, std::
size_t NumSpaceDim>
477template <
unsigned long long cellBitsPerTileDim,
class DecompositionTag>
479 DecompositionTag t1, Face<Dim::K>,
480 const std::array<int, num_space_dim>& off_ijk,
const int halo_width )
const
481 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
484 "Sparse grid implementation doesn't support Face entities so far" );
485 return sharedTileIndexSpaceImpl<cellBitsPerTileDim>( t1, off_ijk,
493template <
class Scalar, std::
size_t NumSpaceDim>
494template <
class DecompositionTag,
class IndexType>
496 DecompositionTag t1, Edge<Dim::I>, IndexType t3 )
const
497 -> IndexSpace<num_space_dim>
500 "Sparse grid implementation doesn't support Edge entities so far" );
501 return indexSpaceImpl( t1, t3 );
505template <
class Scalar, std::
size_t NumSpaceDim>
506template <
class DecompositionTag,
class IndexType>
508 DecompositionTag t1, Edge<Dim::J>, IndexType t3 )
const
509 -> IndexSpace<num_space_dim>
512 "Sparse grid implementation doesn't support Edge entities so far" );
513 return indexSpaceImpl( t1, t3 );
517template <
class Scalar, std::
size_t NumSpaceDim>
518template <
class DecompositionTag,
class IndexType>
520 DecompositionTag t1, Edge<Dim::K>, IndexType t3 )
const
521 -> IndexSpace<num_space_dim>
524 "Sparse grid implementation doesn't support Edge entities so far" );
525 return indexSpaceImpl( t1, t3 );
529template <
class Scalar, std::
size_t NumSpaceDim>
530template <
unsigned long long cellBitsPerTileDim,
class DecompositionTag>
532 DecompositionTag t1, Edge<Dim::I>,
533 const std::array<int, num_space_dim>& off_ijk,
const int halo_width )
const
534 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
537 "Sparse grid implementation doesn't support Edge entities so far" );
538 return sharedTileIndexSpaceImpl<cellBitsPerTileDim>( t1, off_ijk,
543template <
class Scalar, std::
size_t NumSpaceDim>
544template <
unsigned long long cellBitsPerTileDim,
class DecompositionTag>
546 DecompositionTag t1, Edge<Dim::J>,
547 const std::array<int, num_space_dim>& off_ijk,
const int halo_width )
const
548 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
551 "Sparse grid implementation doesn't support Edge entities so far" );
552 return sharedTileIndexSpaceImpl<cellBitsPerTileDim>( t1, off_ijk,
557template <
class Scalar, std::
size_t NumSpaceDim>
558template <
unsigned long long cellBitsPerTileDim,
class DecompositionTag>
560 DecompositionTag t1, Edge<Dim::K>,
561 const std::array<int, num_space_dim>& off_ijk,
const int halo_width )
const
562 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
565 "Sparse grid implementation doesn't support Edge entities so far" );
566 return sharedTileIndexSpaceImpl<cellBitsPerTileDim>( t1, off_ijk,
LocalGrid(const std::shared_ptr< GlobalGrid< mesh_type > > &global_grid, const int halo_cell_width, const long cell_num_per_tile_dim)
Constructor.
Definition Cabana_Grid_SparseLocalGrid_impl.hpp:25
int neighborRank(const std::array< int, num_space_dim > &off_ijk) const
Get the global index of a neighbor given neighbor rank offsets relative to this local grid.
Definition Cabana_Grid_SparseLocalGrid_impl.hpp:98
const GlobalGrid< mesh_type > & globalGrid() const
Get the global grid that owns the local grid.
Definition Cabana_Grid_SparseLocalGrid_impl.hpp:43
int totalNumCell(const int d) const
Get the total number of local cells per dimension (owned + halo).
Definition Cabana_Grid_SparseLocalGrid_impl.hpp:76
int haloCellWidth() const
Get the number of cells in the halo.
Definition Cabana_Grid_SparseLocalGrid_impl.hpp:60
int haloTileWidth() const
Get the number of tiles in the halo.
Definition Cabana_Grid_SparseLocalGrid_impl.hpp:68
static constexpr std::size_t num_space_dim
Spatial dimension.
Definition Cabana_Grid_SparseLocalGrid.hpp:51
Definition Cabana_Grid_SparseLocalGrid.hpp:35
Global logical grid.
Definition Cabana_Grid_GlobalGrid.hpp:39
Structured index space.
Definition Cabana_Grid_IndexSpace.hpp:37
Local logical grid.
Definition Cabana_Grid_LocalGrid.hpp:39
Index space with tile as unit; _min and _max forms the tile range. Note this is for sparse grid only,...
Definition Cabana_Grid_SparseIndexSpace.hpp:1137
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