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(
155 "Cabana::Grid::Experimental::LocalGrid::sharedTileIndexSpace "
156 "(SparseMesh): Neighbor indices out of bounds" );
159 if ( hw > _halo_cell_width )
160 throw std::logic_error(
161 "Cabana::Grid::Experimental::LocalGrid::sharedTileIndexSpace "
162 "(SparseMesh):Requested halo width larger than local grid halo" );
166 if ( neighborRank( off_ijk ) < 0 )
168 std::array<long, num_space_dim> zero_size;
169 for ( std::size_t d = 0; d < num_space_dim; ++d )
176 return sharedTileIndexSpaceImpl<cellBitsPerTileDim>( t1, t2, off_ijk, hw );
181template <
class Scalar, std::
size_t NumSpaceDim>
182template <
unsigned long long cellBitsPerTileDim,
class DecompositionTag,
183 class EntityType, std::size_t NSD>
184std::enable_if_t<3 == NSD, TileIndexSpace<3, cellBitsPerTileDim>>
185LocalGrid<SparseMesh<Scalar, NumSpaceDim>>::sharedTileIndexSpace(
186 DecompositionTag t1, EntityType t2,
const int off_i,
const int off_j,
187 const int off_k,
const int halo_width )
const
189 std::array<int, 3> off_ijk = { off_i, off_j, off_k };
190 return sharedTileIndexSpace<cellBitsPerTileDim>( t1, t2, off_ijk,
198template <
class Scalar, std::
size_t NumSpaceDim>
201 -> IndexSpace<num_space_dim>
204 std::array<long, num_space_dim> min;
205 for ( std::size_t d = 0; d < num_space_dim; ++d )
206 min[d] = _halo_cell_width;
209 std::array<long, num_space_dim> max;
210 for ( std::size_t d = 0; d < num_space_dim; ++d )
211 max[d] = min[d] + _global_grid->ownedNumCell( d );
213 return IndexSpace<num_space_dim>( min, max );
219template <
class Scalar, std::
size_t NumSpaceDim>
222 -> IndexSpace<num_space_dim>
225 std::array<long, num_space_dim>
size;
226 for ( std::size_t d = 0; d < num_space_dim; ++d )
228 size[d] = totalNumCell( d );
231 return IndexSpace<num_space_dim>(
size );
236template <
class Scalar, std::
size_t NumSpaceDim>
239 -> IndexSpace<num_space_dim>
242 std::array<long, num_space_dim> min;
243 for ( std::size_t d = 0; d < num_space_dim; ++d )
244 min[d] = _global_grid->globalOffset( d );
247 std::array<long, num_space_dim> max;
248 for ( std::size_t d = 0; d < num_space_dim; ++d )
249 max[d] = min[d] + _global_grid->ownedNumCell( d );
251 return IndexSpace<num_space_dim>( min, max );
257template <
class Scalar, std::
size_t NumSpaceDim>
258template <
unsigned long long cellBitsPerTileDim>
260 Own,
const std::array<int, num_space_dim>& off_ijk,
261 const int halo_width )
const
262 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
264 auto owned_cell_space = indexSpaceImpl( Own(), Node(), Global() );
266 std::array<long, num_space_dim> min;
267 for ( std::size_t d = 0; d < num_space_dim; ++d )
270 if ( -1 == off_ijk[d] )
271 min[d] = owned_cell_space.min( d ) >> cellBitsPerTileDim;
274 else if ( 0 == off_ijk[d] )
275 min[d] = owned_cell_space.min( d ) >> cellBitsPerTileDim;
278 else if ( 1 == off_ijk[d] )
279 min[d] = ( owned_cell_space.max( d ) - halo_width ) >>
282 throw std::runtime_error(
283 "Cabana::Grid::Experimental::LocalGrid::sharedTileIndexSpace "
284 "(SparseMesh): Neighbor offset must be 1, 0, or -1" );
288 std::array<long, num_space_dim> max;
289 for ( std::size_t d = 0; d < num_space_dim; ++d )
292 if ( -1 == off_ijk[d] )
293 max[d] = ( owned_cell_space.min( d ) + halo_width ) >>
297 else if ( 0 == off_ijk[d] )
298 max[d] = owned_cell_space.max( d ) >> cellBitsPerTileDim;
301 else if ( 1 == off_ijk[d] )
302 max[d] = owned_cell_space.max( d ) >> cellBitsPerTileDim;
304 throw std::runtime_error(
305 "Cabana::Grid::Experimental::LocalGrid::sharedTileIndexSpace "
306 "(SparseMesh): Neighbor offset must be 1, 0, or -1" );
309 return TileIndexSpace<num_space_dim, cellBitsPerTileDim>( min, max );
315template <
class Scalar, std::
size_t NumSpaceDim>
316template <
unsigned long long cellBitsPerTileDim>
318 Ghost,
const std::array<int, num_space_dim>& off_ijk,
319 const int halo_width )
const
320 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
323 auto owned_cell_space = indexSpaceImpl( Own(), Node(), Global() );
326 std::array<long, num_space_dim> min;
327 for ( std::size_t d = 0; d < num_space_dim; ++d )
330 if ( -1 == off_ijk[d] )
331 min[d] = ( owned_cell_space.min( d ) - halo_width ) >>
335 else if ( 0 == off_ijk[d] )
336 min[d] = owned_cell_space.min( d ) >> cellBitsPerTileDim;
339 else if ( 1 == off_ijk[d] )
340 min[d] = owned_cell_space.max( d ) >> cellBitsPerTileDim;
342 throw std::runtime_error(
343 "Cabana::Grid::Experimental::LocalGrid::sharedTileIndexSpace "
344 "(SparseMesh): Neighbor offset must be 1, 0, or -1" );
348 std::array<long, num_space_dim> max;
349 for ( std::size_t d = 0; d < num_space_dim; ++d )
352 if ( -1 == off_ijk[d] )
353 max[d] = owned_cell_space.min( d ) >> cellBitsPerTileDim;
356 else if ( 0 == off_ijk[d] )
357 max[d] = owned_cell_space.max( d ) >> cellBitsPerTileDim;
360 else if ( 1 == off_ijk[d] )
361 max[d] = ( owned_cell_space.max( d ) + halo_width ) >>
364 throw std::runtime_error(
365 "Cabana::Grid::Experimental::LocalGrid::sharedTileIndexSpace "
366 "(SparseMesh): Neighbor offset must be 1, 0, or -1" );
369 return TileIndexSpace<num_space_dim, cellBitsPerTileDim>( min, max );
376template <
class Scalar, std::
size_t NumSpaceDim>
377template <
class DecompositionTag,
class IndexType>
379 DecompositionTag t1, Node, IndexType t3 )
const -> IndexSpace<num_space_dim>
381 return indexSpaceImpl( t1, t3 );
385template <
class Scalar, std::
size_t NumSpaceDim>
386template <
unsigned long long cellBitsPerTileDim,
class DecompositionTag>
388 DecompositionTag t1, Node,
const std::array<int, num_space_dim>& off_ijk,
389 const int halo_width )
const
390 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
392 return sharedTileIndexSpaceImpl<cellBitsPerTileDim>( t1, off_ijk,
400template <
class Scalar, std::
size_t NumSpaceDim>
401template <
class DecompositionTag,
class IndexType>
403 DecompositionTag t1, Cell, IndexType t3 )
const -> IndexSpace<num_space_dim>
405 return indexSpaceImpl( t1, t3 );
409template <
class Scalar, std::
size_t NumSpaceDim>
410template <
unsigned long long cellBitsPerTileDim,
class DecompositionTag>
412 DecompositionTag t1, Cell,
const std::array<int, num_space_dim>& off_ijk,
413 const int halo_width )
const
414 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
416 return sharedTileIndexSpaceImpl<cellBitsPerTileDim>( t1, off_ijk,
424template <
class Scalar, std::
size_t NumSpaceDim>
425template <
class DecompositionTag,
class IndexType>
427 DecompositionTag t1, Face<Dim::I>, IndexType t3 )
const
428 -> IndexSpace<num_space_dim>
431 "Cabana::Grid::Experimental::LocalGrid::indexSpace "
432 "(SparseMesh): Implementation doesn't support Face entities." );
433 return indexSpaceImpl( t1, t3 );
437template <
class Scalar, std::
size_t NumSpaceDim>
438template <
class DecompositionTag,
class IndexType>
440 DecompositionTag t1, Face<Dim::J>, IndexType t3 )
const
441 -> IndexSpace<num_space_dim>
444 "Cabana::Grid::Experimental::LocalGrid::indexSpace "
445 "(SparseMesh): Implementation doesn't support Face entities." );
446 return indexSpaceImpl( t1, t3 );
450template <
class Scalar, std::
size_t NumSpaceDim>
451template <
class DecompositionTag,
class IndexType>
453 DecompositionTag t1, Face<Dim::K>, IndexType t3 )
const
454 -> IndexSpace<num_space_dim>
456 std::runtime_error(
"Cabana::Grid::Experimental::LocalGrid::indexSpace "
457 "(SparseMesh): Sparse grid implementation doesn't "
458 "support Face entities." );
459 return indexSpaceImpl( t1, t3 );
463template <
class Scalar, std::
size_t NumSpaceDim>
464template <
unsigned long long cellBitsPerTileDim,
class DecompositionTag>
466 DecompositionTag t1, Face<Dim::I>,
467 const std::array<int, num_space_dim>& off_ijk,
const int halo_width )
const
468 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
471 "Cabana::Grid::Experimental::LocalGrid::indexSpace "
472 "(SparseMesh): Implementation doesn't support Face entities." );
473 return sharedTileIndexSpaceImpl<cellBitsPerTileDim>( t1, off_ijk,
478template <
class Scalar, std::
size_t NumSpaceDim>
479template <
unsigned long long cellBitsPerTileDim,
class DecompositionTag>
481 DecompositionTag t1, Face<Dim::J>,
482 const std::array<int, num_space_dim>& off_ijk,
const int halo_width )
const
483 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
486 "Cabana::Grid::Experimental::LocalGrid::indexSpace "
487 "(SparseMesh): Implementation doesn't support Face entities." );
488 return sharedTileIndexSpaceImpl<cellBitsPerTileDim>( t1, off_ijk,
492template <
class Scalar, std::
size_t NumSpaceDim>
493template <
unsigned long long cellBitsPerTileDim,
class DecompositionTag>
495 DecompositionTag t1, Face<Dim::K>,
496 const std::array<int, num_space_dim>& off_ijk,
const int halo_width )
const
497 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
500 "Cabana::Grid::Experimental::LocalGrid::indexSpace "
501 "(SparseMesh): Implementation doesn't support Face entities." );
502 return sharedTileIndexSpaceImpl<cellBitsPerTileDim>( t1, off_ijk,
510template <
class Scalar, std::
size_t NumSpaceDim>
511template <
class DecompositionTag,
class IndexType>
513 DecompositionTag t1, Edge<Dim::I>, IndexType t3 )
const
514 -> IndexSpace<num_space_dim>
517 "Cabana::Grid::Experimental::LocalGrid::indexSpace "
518 "(SparseMesh): Implementation doesn't support Edge entities." );
519 return indexSpaceImpl( t1, t3 );
523template <
class Scalar, std::
size_t NumSpaceDim>
524template <
class DecompositionTag,
class IndexType>
526 DecompositionTag t1, Edge<Dim::J>, IndexType t3 )
const
527 -> IndexSpace<num_space_dim>
530 "Cabana::Grid::Experimental::LocalGrid::indexSpace "
531 "(SparseMesh): Implementation doesn't support Edge entities." );
532 return indexSpaceImpl( t1, t3 );
536template <
class Scalar, std::
size_t NumSpaceDim>
537template <
class DecompositionTag,
class IndexType>
539 DecompositionTag t1, Edge<Dim::K>, IndexType t3 )
const
540 -> IndexSpace<num_space_dim>
543 "Cabana::Grid::Experimental::LocalGrid::indexSpace "
544 "(SparseMesh): Implementation doesn't support Edge entities." );
545 return indexSpaceImpl( t1, t3 );
549template <
class Scalar, std::
size_t NumSpaceDim>
550template <
unsigned long long cellBitsPerTileDim,
class DecompositionTag>
552 DecompositionTag t1, Edge<Dim::I>,
553 const std::array<int, num_space_dim>& off_ijk,
const int halo_width )
const
554 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
557 "Cabana::Grid::Experimental::LocalGrid::sharedTileIndexSpace "
558 "(SparseMesh): Implementation doesn't support Edge entities." );
559 return sharedTileIndexSpaceImpl<cellBitsPerTileDim>( t1, off_ijk,
564template <
class Scalar, std::
size_t NumSpaceDim>
565template <
unsigned long long cellBitsPerTileDim,
class DecompositionTag>
567 DecompositionTag t1, Edge<Dim::J>,
568 const std::array<int, num_space_dim>& off_ijk,
const int halo_width )
const
569 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
572 "Cabana::Grid::Experimental::LocalGrid::sharedTileIndexSpace "
573 "(SparseMesh): Implementation doesn't support Edge entities." );
574 return sharedTileIndexSpaceImpl<cellBitsPerTileDim>( t1, off_ijk,
579template <
class Scalar, std::
size_t NumSpaceDim>
580template <
unsigned long long cellBitsPerTileDim,
class DecompositionTag>
582 DecompositionTag t1, Edge<Dim::K>,
583 const std::array<int, num_space_dim>& off_ijk,
const int halo_width )
const
584 -> TileIndexSpace<num_space_dim, cellBitsPerTileDim>
587 "Cabana::Grid::Experimental::LocalGrid::sharedTileIndexSpace "
588 "(SparseMesh): Implementation doesn't support Edge entities." );
589 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