16#ifndef CABANA_GRID_LOCALMESH_HPP
17#define CABANA_GRID_LOCALMESH_HPP
24#include <Kokkos_Core.hpp>
32template <
class MemorySpace,
class MeshType>
37template <
class Scalar,
class MemorySpace, std::
size_t NumSpaceDim>
52 static_assert( Kokkos::is_memory_space<MemorySpace>() );
63 const auto& global_grid = local_grid.globalGrid();
64 const auto& global_mesh = global_grid.globalMesh();
68 _cell_size[d] = global_mesh.cellSize( d );
73 _face_area[Dim::I] = _cell_size[Dim::J] * _cell_size[Dim::K];
74 _face_area[Dim::J] = _cell_size[Dim::I] * _cell_size[Dim::K];
75 _face_area[Dim::K] = _cell_size[Dim::I] * _cell_size[Dim::J];
79 _face_area[Dim::I] = _cell_size[Dim::J];
80 _face_area[Dim::J] = _cell_size[Dim::I];
86 _cell_volume *= _cell_size[d];
90 _own_low_corner[d] = global_mesh.lowCorner( d ) +
91 _cell_size[d] * global_grid.globalOffset( d );
96 global_mesh.lowCorner( d ) +
97 _cell_size[d] * ( global_grid.globalOffset( d ) +
98 global_grid.ownedNumCell( d ) );
103 local_grid.haloCellWidth() * _cell_size[d];
108 local_grid.haloCellWidth() * _cell_size[d];
112 _periodic[d] = global_grid.isPeriodic( d );
117 _boundary_lo[d] = global_grid.onLowBoundary( d );
118 _boundary_hi[d] = global_grid.onHighBoundary( d );
123 KOKKOS_INLINE_FUNCTION
124 bool isPeriodic(
const int dim )
const {
return _periodic[dim]; }
127 KOKKOS_INLINE_FUNCTION
131 KOKKOS_INLINE_FUNCTION
136 KOKKOS_INLINE_FUNCTION
139 return _own_low_corner[dim];
145 KOKKOS_INLINE_FUNCTION
148 return _ghost_low_corner[dim];
153 KOKKOS_INLINE_FUNCTION
156 return _own_high_corner[dim];
162 KOKKOS_INLINE_FUNCTION
165 return _ghost_high_corner[dim];
169 template <
typename Decomposition>
170 KOKKOS_FUNCTION Scalar
extent( Decomposition d,
const int dim )
const
179 template <
class Integer>
185 x[d] = _ghost_low_corner[d] +
186 ( Scalar( index[d] ) + Scalar( 0.5 ) ) * _cell_size[d];
193 template <
class Integer>
199 x[d] = _ghost_low_corner[d] + Scalar( index[d] ) * _cell_size[d];
206 template <
int Dir,
class Integer>
211 static_assert( Dir <
num_space_dim,
"Face dimension out of bounds" );
215 _ghost_low_corner[d] + Scalar( index[d] ) * _cell_size[d];
217 x[d] = _ghost_low_corner[d] +
218 ( Scalar( index[d] ) + Scalar( 0.5 ) ) * _cell_size[d];
225 template <
int Dir,
class Integer, std::
size_t NSD = num_space_dim>
226 KOKKOS_INLINE_FUNCTION std::enable_if_t<3 == NSD, void>
229 for ( std::size_t d = 0; d < 3; ++d )
231 x[d] = _ghost_low_corner[d] +
232 ( Scalar( index[d] ) + Scalar( 0.5 ) ) * _cell_size[d];
235 _ghost_low_corner[d] + Scalar( index[d] ) * _cell_size[d];
242 template <
class Integer>
253 template <
int Dir,
class Integer, std::
size_t NSD = num_space_dim>
254 KOKKOS_INLINE_FUNCTION std::enable_if_t<3 == NSD, Scalar>
257 return _cell_size[Dir];
264 template <
int Dir,
class Integer>
268 static_assert( Dir <
num_space_dim,
"Face dimension out of bounds" );
269 return _face_area[Dir];
276 template <
class Integer>
284 Kokkos::Array<Scalar, num_space_dim> _cell_size;
285 Kokkos::Array<Scalar, num_space_dim> _face_area;
287 Kokkos::Array<Scalar, num_space_dim> _own_low_corner;
288 Kokkos::Array<Scalar, num_space_dim> _own_high_corner;
289 Kokkos::Array<Scalar, num_space_dim> _ghost_low_corner;
290 Kokkos::Array<Scalar, num_space_dim> _ghost_high_corner;
291 Kokkos::Array<bool, num_space_dim> _periodic;
292 Kokkos::Array<bool, num_space_dim> _boundary_lo;
293 Kokkos::Array<bool, num_space_dim> _boundary_hi;
298template <
class Scalar,
class MemorySpace, std::
size_t NumSpaceDim>
313 static_assert( Kokkos::is_memory_space<MemorySpace>() );
322 const auto& global_grid = local_grid.globalGrid();
323 const auto& global_mesh = global_grid.globalMesh();
328 global_mesh.nonUniformEdge( d )[global_grid.globalOffset( d )];
332 _own_high_corner[d] =
333 global_mesh.nonUniformEdge( d )[global_grid.globalOffset( d ) +
334 global_grid.ownedNumCell( d )];
340 if ( !global_grid.onLowBoundary( d ) )
342 _ghost_low_corner[d] = global_mesh.nonUniformEdge(
343 d )[global_grid.globalOffset( d ) -
344 local_grid.haloCellWidth()];
349 else if ( global_grid.isPeriodic( d ) )
351 int nedge = global_mesh.nonUniformEdge( d ).size();
352 _ghost_low_corner[d] =
353 global_mesh.nonUniformEdge( d ).front() -
354 ( global_mesh.nonUniformEdge( d ).back() -
355 global_mesh.nonUniformEdge(
356 d )[nedge - local_grid.haloCellWidth() - 1] );
363 Scalar dx = global_mesh.nonUniformEdge( d )[1] -
364 global_mesh.nonUniformEdge( d )[0];
365 _ghost_low_corner[d] = global_mesh.nonUniformEdge( d ).front() -
366 dx * local_grid.haloCellWidth();
374 if ( !global_grid.onHighBoundary( d ) )
376 _ghost_high_corner[d] = global_mesh.nonUniformEdge(
377 d )[global_grid.globalOffset( d ) +
378 global_grid.ownedNumCell( d ) +
379 local_grid.haloCellWidth()];
384 else if ( global_grid.isPeriodic( d ) )
386 _ghost_high_corner[d] =
387 global_mesh.nonUniformEdge( d ).back() +
388 ( global_mesh.nonUniformEdge(
389 d )[local_grid.haloCellWidth()] -
390 global_mesh.nonUniformEdge( d ).front() );
397 int nedge = global_mesh.nonUniformEdge( d ).size();
398 Scalar dx = global_mesh.nonUniformEdge( d )[nedge - 1] -
399 global_mesh.nonUniformEdge( d )[nedge - 2];
400 _ghost_high_corner[d] = global_mesh.nonUniformEdge( d ).back() +
401 dx * local_grid.haloCellWidth();
406 auto owned_nodes_local =
408 auto ghosted_nodes_local =
410 auto owned_nodes_global =
415 const auto& global_edge = global_mesh.nonUniformEdge( d );
416 int nedge = ghosted_nodes_local.extent( d );
417 int nedge_global = global_edge.size();
418 _local_edges[d] = Kokkos::View<Scalar*, MemorySpace>(
419 Kokkos::ViewAllocateWithoutInitializing(
"local_edges" ),
423 auto edge_mirror = Kokkos::create_mirror_view( Kokkos::HostSpace(),
427 for (
int n = owned_nodes_local.min( d );
428 n < owned_nodes_local.max( d ); ++n )
430 edge_mirror( n ) = global_edge[owned_nodes_global.min( d ) + n -
431 owned_nodes_local.min( d )];
435 if ( !global_grid.onLowBoundary( d ) )
438 for (
int n = 0; n < owned_nodes_local.min( d ); ++n )
441 global_edge[owned_nodes_global.min( d ) + n -
442 owned_nodes_local.min( d )];
445 else if ( global_grid.isPeriodic( d ) )
449 for (
int n = 0; n < owned_nodes_local.min( d ); ++n )
452 global_edge.front() - global_edge.back() +
453 global_edge[global_edge.size() - 1 -
454 local_grid.haloCellWidth() + n];
461 for (
int n = 0; n < owned_nodes_local.min( d ); ++n )
463 Scalar dx = global_edge[1] - global_edge[0];
464 edge_mirror( n ) = global_edge.front() -
465 ( owned_nodes_local.min( d ) - n ) * dx;
470 if ( !global_grid.onHighBoundary( d ) )
473 for (
int n = owned_nodes_local.max( d );
474 n < ghosted_nodes_local.max( d ); ++n )
477 global_edge[owned_nodes_global.min( d ) + n -
478 owned_nodes_local.min( d )];
481 else if ( global_grid.isPeriodic( d ) )
485 for (
int n = 0; n < ghosted_nodes_local.max( d ) -
486 owned_nodes_local.max( d );
489 edge_mirror( owned_nodes_local.max( d ) + n ) =
490 global_edge.back() + global_edge[n] -
498 for (
int n = owned_nodes_local.max( d );
499 n < ghosted_nodes_local.max( d ); ++n )
501 Scalar dx = global_edge[nedge_global - 1] -
502 global_edge[nedge_global - 2];
505 ( n - owned_nodes_local.max( d ) + 1 ) * dx;
510 Kokkos::deep_copy( _local_edges[d], edge_mirror );
515 _periodic[d] = global_grid.isPeriodic( d );
520 _boundary_lo[d] = global_grid.onLowBoundary( d );
521 _boundary_hi[d] = global_grid.onHighBoundary( d );
527 KOKKOS_INLINE_FUNCTION
528 bool isPeriodic(
const int dim )
const {
return _periodic[dim]; }
532 KOKKOS_INLINE_FUNCTION
537 KOKKOS_INLINE_FUNCTION
542 KOKKOS_INLINE_FUNCTION
545 return _own_low_corner[dim];
551 KOKKOS_INLINE_FUNCTION
554 return _ghost_low_corner[dim];
559 KOKKOS_INLINE_FUNCTION
562 return _own_high_corner[dim];
568 KOKKOS_INLINE_FUNCTION
571 return _ghost_high_corner[dim];
577 template <
typename Decomposition>
578 KOKKOS_FUNCTION Scalar
extent( Decomposition d,
const int dim )
const
590 template <
class Integer>
596 x[d] = ( _local_edges[d]( index[d] + 1 ) +
597 _local_edges[d]( index[d] ) ) /
607 template <
class Integer>
613 x[d] = _local_edges[d]( index[d] );
622 template <
int Dir,
class Integer>
627 static_assert( Dir <
num_space_dim,
"Face dimension out of bounds" );
631 x[d] = _local_edges[d]( index[d] );
633 x[d] = ( _local_edges[d]( index[d] + 1 ) +
634 _local_edges[d]( index[d] ) ) /
644 template <
int Dir,
class Integer, std::
size_t NSD = num_space_dim>
645 KOKKOS_INLINE_FUNCTION std::enable_if_t<3 == NSD, void>
648 for ( std::size_t d = 0; d < 3; ++d )
650 x[d] = ( _local_edges[d]( index[d] + 1 ) +
651 _local_edges[d]( index[d] ) ) /
654 x[d] = _local_edges[d]( index[d] );
660 template <
class Integer>
672 template <
int Dir,
class Integer, std::
size_t NSD = num_space_dim>
673 KOKKOS_INLINE_FUNCTION std::enable_if_t<3 == NSD, Scalar>
676 return _local_edges[Dir][index[Dir] + 1] -
677 _local_edges[Dir][index[Dir]];
685 template <
class Integer, std::
size_t NSD = num_space_dim>
686 KOKKOS_INLINE_FUNCTION std::enable_if_t<3 == NSD, Scalar>
698 template <
class Integer, std::
size_t NSD = num_space_dim>
699 KOKKOS_INLINE_FUNCTION std::enable_if_t<3 == NSD, Scalar>
711 template <
class Integer, std::
size_t NSD = num_space_dim>
712 KOKKOS_INLINE_FUNCTION std::enable_if_t<3 == NSD, Scalar>
724 template <
class Integer, std::
size_t NSD = num_space_dim>
725 KOKKOS_INLINE_FUNCTION std::enable_if_t<2 == NSD, Scalar>
728 return _local_edges[Dim::J][index[Dim::J] + 1] -
729 _local_edges[Dim::J][index[Dim::J]];
737 template <
class Integer, std::
size_t NSD = num_space_dim>
738 KOKKOS_INLINE_FUNCTION std::enable_if_t<2 == NSD, Scalar>
741 return _local_edges[Dim::I][index[Dim::I] + 1] -
742 _local_edges[Dim::I][index[Dim::I]];
750 template <
class Integer>
751 KOKKOS_INLINE_FUNCTION Scalar
756 m *= _local_edges[d][index[d] + 1] - _local_edges[d][index[d]];
761 Kokkos::Array<Scalar, num_space_dim> _own_low_corner;
762 Kokkos::Array<Scalar, num_space_dim> _own_high_corner;
763 Kokkos::Array<Scalar, num_space_dim> _ghost_low_corner;
764 Kokkos::Array<Scalar, num_space_dim> _ghost_high_corner;
765 Kokkos::Array<Kokkos::View<Scalar*, MemorySpace>, num_space_dim>
767 Kokkos::Array<bool, num_space_dim> _periodic;
768 Kokkos::Array<bool, num_space_dim> _boundary_lo;
769 Kokkos::Array<bool, num_space_dim> _boundary_hi;
777template <
class MemorySpace,
class MeshType>
778LocalMesh<MemorySpace, MeshType>
LocalMesh< MemorySpace, MeshType > createLocalMesh(const LocalGrid< MeshType > &local_grid)
Creation function for local mesh.
Definition Cabana_Grid_LocalMesh.hpp:779
Local logical grid.
Definition Cabana_Grid_LocalGrid.hpp:39
Definition Cabana_Grid_LocalMesh.hpp:33
Core: particle data structures and algorithms.
Definition Cabana_AoSoA.hpp:36
Mesh cell tag.
Definition Cabana_Grid_Types.hpp:49
Mesh edge tag.
Definition Cabana_Grid_Types.hpp:95
Mesh face tag.
Definition Cabana_Grid_Types.hpp:64
Ghosted decomposition tag.
Definition Cabana_Grid_Types.hpp:197
Global index tag.
Definition Cabana_Grid_Types.hpp:215
Local index tag.
Definition Cabana_Grid_Types.hpp:208
Mesh node tag.
Definition Cabana_Grid_Types.hpp:56
Owned decomposition tag.
Definition Cabana_Grid_Types.hpp:190