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>
56 Cabana::Impl::deprecated( Kokkos::is_device<MemorySpace>() ) );
59 using device_type [[deprecated]] =
typename memory_space::device_type;
69 const auto& global_grid = local_grid.globalGrid();
70 const auto& global_mesh = global_grid.globalMesh();
74 _cell_size[d] = global_mesh.cellSize( d );
79 _face_area[Dim::I] = _cell_size[Dim::J] * _cell_size[Dim::K];
80 _face_area[Dim::J] = _cell_size[Dim::I] * _cell_size[Dim::K];
81 _face_area[Dim::K] = _cell_size[Dim::I] * _cell_size[Dim::J];
85 _face_area[Dim::I] = _cell_size[Dim::J];
86 _face_area[Dim::J] = _cell_size[Dim::I];
92 _cell_volume *= _cell_size[d];
96 _own_low_corner[d] = global_mesh.lowCorner( d ) +
97 _cell_size[d] * global_grid.globalOffset( d );
101 _own_high_corner[d] =
102 global_mesh.lowCorner( d ) +
103 _cell_size[d] * ( global_grid.globalOffset( d ) +
104 global_grid.ownedNumCell( d ) );
109 local_grid.haloCellWidth() * _cell_size[d];
114 local_grid.haloCellWidth() * _cell_size[d];
118 _periodic[d] = global_grid.isPeriodic( d );
123 _boundary_lo[d] = global_grid.onLowBoundary( d );
124 _boundary_hi[d] = global_grid.onHighBoundary( d );
129 KOKKOS_INLINE_FUNCTION
130 bool isPeriodic(
const int dim )
const {
return _periodic[dim]; }
133 KOKKOS_INLINE_FUNCTION
137 KOKKOS_INLINE_FUNCTION
142 KOKKOS_INLINE_FUNCTION
145 return _own_low_corner[dim];
151 KOKKOS_INLINE_FUNCTION
154 return _ghost_low_corner[dim];
159 KOKKOS_INLINE_FUNCTION
162 return _own_high_corner[dim];
168 KOKKOS_INLINE_FUNCTION
171 return _ghost_high_corner[dim];
175 template <
typename Decomposition>
176 KOKKOS_FUNCTION Scalar
extent( Decomposition d,
const int dim )
const
185 template <
class Integer>
191 x[d] = _ghost_low_corner[d] +
192 ( Scalar( index[d] ) + Scalar( 0.5 ) ) * _cell_size[d];
199 template <
class Integer>
205 x[d] = _ghost_low_corner[d] + Scalar( index[d] ) * _cell_size[d];
212 template <
int Dir,
class Integer>
217 static_assert( Dir <
num_space_dim,
"Face dimension out of bounds" );
221 _ghost_low_corner[d] + Scalar( index[d] ) * _cell_size[d];
223 x[d] = _ghost_low_corner[d] +
224 ( Scalar( index[d] ) + Scalar( 0.5 ) ) * _cell_size[d];
231 template <
int Dir,
class Integer, std::
size_t NSD = num_space_dim>
232 KOKKOS_INLINE_FUNCTION std::enable_if_t<3 == NSD, void>
235 for ( std::size_t d = 0; d < 3; ++d )
237 x[d] = _ghost_low_corner[d] +
238 ( Scalar( index[d] ) + Scalar( 0.5 ) ) * _cell_size[d];
241 _ghost_low_corner[d] + Scalar( index[d] ) * _cell_size[d];
248 template <
class Integer>
259 template <
int Dir,
class Integer, std::
size_t NSD = num_space_dim>
260 KOKKOS_INLINE_FUNCTION std::enable_if_t<3 == NSD, Scalar>
263 return _cell_size[Dir];
270 template <
int Dir,
class Integer>
274 static_assert( Dir <
num_space_dim,
"Face dimension out of bounds" );
275 return _face_area[Dir];
282 template <
class Integer>
290 Kokkos::Array<Scalar, num_space_dim> _cell_size;
291 Kokkos::Array<Scalar, num_space_dim> _face_area;
293 Kokkos::Array<Scalar, num_space_dim> _own_low_corner;
294 Kokkos::Array<Scalar, num_space_dim> _own_high_corner;
295 Kokkos::Array<Scalar, num_space_dim> _ghost_low_corner;
296 Kokkos::Array<Scalar, num_space_dim> _ghost_high_corner;
297 Kokkos::Array<bool, num_space_dim> _periodic;
298 Kokkos::Array<bool, num_space_dim> _boundary_lo;
299 Kokkos::Array<bool, num_space_dim> _boundary_hi;
304template <
class Scalar,
class MemorySpace, std::
size_t NumSpaceDim>
323 Cabana::Impl::deprecated( Kokkos::is_device<MemorySpace>() ) );
326 using device_type [[deprecated]] =
typename memory_space::device_type;
334 const auto& global_grid = local_grid.globalGrid();
335 const auto& global_mesh = global_grid.globalMesh();
340 global_mesh.nonUniformEdge( d )[global_grid.globalOffset( d )];
344 _own_high_corner[d] =
345 global_mesh.nonUniformEdge( d )[global_grid.globalOffset( d ) +
346 global_grid.ownedNumCell( d )];
352 if ( !global_grid.onLowBoundary( d ) )
354 _ghost_low_corner[d] = global_mesh.nonUniformEdge(
355 d )[global_grid.globalOffset( d ) -
356 local_grid.haloCellWidth()];
361 else if ( global_grid.isPeriodic( d ) )
363 int nedge = global_mesh.nonUniformEdge( d ).size();
364 _ghost_low_corner[d] =
365 global_mesh.nonUniformEdge( d ).front() -
366 ( global_mesh.nonUniformEdge( d ).back() -
367 global_mesh.nonUniformEdge(
368 d )[nedge - local_grid.haloCellWidth() - 1] );
375 Scalar dx = global_mesh.nonUniformEdge( d )[1] -
376 global_mesh.nonUniformEdge( d )[0];
377 _ghost_low_corner[d] = global_mesh.nonUniformEdge( d ).front() -
378 dx * local_grid.haloCellWidth();
386 if ( !global_grid.onHighBoundary( d ) )
388 _ghost_high_corner[d] = global_mesh.nonUniformEdge(
389 d )[global_grid.globalOffset( d ) +
390 global_grid.ownedNumCell( d ) +
391 local_grid.haloCellWidth()];
396 else if ( global_grid.isPeriodic( d ) )
398 _ghost_high_corner[d] =
399 global_mesh.nonUniformEdge( d ).back() +
400 ( global_mesh.nonUniformEdge(
401 d )[local_grid.haloCellWidth()] -
402 global_mesh.nonUniformEdge( d ).front() );
409 int nedge = global_mesh.nonUniformEdge( d ).size();
410 Scalar dx = global_mesh.nonUniformEdge( d )[nedge - 1] -
411 global_mesh.nonUniformEdge( d )[nedge - 2];
412 _ghost_high_corner[d] = global_mesh.nonUniformEdge( d ).back() +
413 dx * local_grid.haloCellWidth();
418 auto owned_nodes_local =
420 auto ghosted_nodes_local =
422 auto owned_nodes_global =
427 const auto& global_edge = global_mesh.nonUniformEdge( d );
428 int nedge = ghosted_nodes_local.extent( d );
429 int nedge_global = global_edge.size();
430 _local_edges[d] = Kokkos::View<Scalar*, MemorySpace>(
431 Kokkos::ViewAllocateWithoutInitializing(
"local_edges" ),
435 auto edge_mirror = Kokkos::create_mirror_view( Kokkos::HostSpace(),
439 for (
int n = owned_nodes_local.min( d );
440 n < owned_nodes_local.max( d ); ++n )
442 edge_mirror( n ) = global_edge[owned_nodes_global.min( d ) + n -
443 owned_nodes_local.min( d )];
447 if ( !global_grid.onLowBoundary( d ) )
450 for (
int n = 0; n < owned_nodes_local.min( d ); ++n )
453 global_edge[owned_nodes_global.min( d ) + n -
454 owned_nodes_local.min( d )];
457 else if ( global_grid.isPeriodic( d ) )
461 for (
int n = 0; n < owned_nodes_local.min( d ); ++n )
464 global_edge.front() - global_edge.back() +
465 global_edge[global_edge.size() - 1 -
466 local_grid.haloCellWidth() + n];
473 for (
int n = 0; n < owned_nodes_local.min( d ); ++n )
475 Scalar dx = global_edge[1] - global_edge[0];
476 edge_mirror( n ) = global_edge.front() -
477 ( owned_nodes_local.min( d ) - n ) * dx;
482 if ( !global_grid.onHighBoundary( d ) )
485 for (
int n = owned_nodes_local.max( d );
486 n < ghosted_nodes_local.max( d ); ++n )
489 global_edge[owned_nodes_global.min( d ) + n -
490 owned_nodes_local.min( d )];
493 else if ( global_grid.isPeriodic( d ) )
497 for (
int n = 0; n < ghosted_nodes_local.max( d ) -
498 owned_nodes_local.max( d );
501 edge_mirror( owned_nodes_local.max( d ) + n ) =
502 global_edge.back() + global_edge[n] -
510 for (
int n = owned_nodes_local.max( d );
511 n < ghosted_nodes_local.max( d ); ++n )
513 Scalar dx = global_edge[nedge_global - 1] -
514 global_edge[nedge_global - 2];
517 ( n - owned_nodes_local.max( d ) + 1 ) * dx;
522 Kokkos::deep_copy( _local_edges[d], edge_mirror );
527 _periodic[d] = global_grid.isPeriodic( d );
532 _boundary_lo[d] = global_grid.onLowBoundary( d );
533 _boundary_hi[d] = global_grid.onHighBoundary( d );
539 KOKKOS_INLINE_FUNCTION
540 bool isPeriodic(
const int dim )
const {
return _periodic[dim]; }
544 KOKKOS_INLINE_FUNCTION
549 KOKKOS_INLINE_FUNCTION
554 KOKKOS_INLINE_FUNCTION
557 return _own_low_corner[dim];
563 KOKKOS_INLINE_FUNCTION
566 return _ghost_low_corner[dim];
571 KOKKOS_INLINE_FUNCTION
574 return _own_high_corner[dim];
580 KOKKOS_INLINE_FUNCTION
583 return _ghost_high_corner[dim];
589 template <
typename Decomposition>
590 KOKKOS_FUNCTION Scalar
extent( Decomposition d,
const int dim )
const
602 template <
class Integer>
608 x[d] = ( _local_edges[d]( index[d] + 1 ) +
609 _local_edges[d]( index[d] ) ) /
619 template <
class Integer>
625 x[d] = _local_edges[d]( index[d] );
634 template <
int Dir,
class Integer>
639 static_assert( Dir <
num_space_dim,
"Face dimension out of bounds" );
643 x[d] = _local_edges[d]( index[d] );
645 x[d] = ( _local_edges[d]( index[d] + 1 ) +
646 _local_edges[d]( index[d] ) ) /
656 template <
int Dir,
class Integer, std::
size_t NSD = num_space_dim>
657 KOKKOS_INLINE_FUNCTION std::enable_if_t<3 == NSD, void>
660 for ( std::size_t d = 0; d < 3; ++d )
662 x[d] = ( _local_edges[d]( index[d] + 1 ) +
663 _local_edges[d]( index[d] ) ) /
666 x[d] = _local_edges[d]( index[d] );
672 template <
class Integer>
684 template <
int Dir,
class Integer, std::
size_t NSD = num_space_dim>
685 KOKKOS_INLINE_FUNCTION std::enable_if_t<3 == NSD, Scalar>
688 return _local_edges[Dir][index[Dir] + 1] -
689 _local_edges[Dir][index[Dir]];
697 template <
class Integer, std::
size_t NSD = num_space_dim>
698 KOKKOS_INLINE_FUNCTION std::enable_if_t<3 == NSD, Scalar>
710 template <
class Integer, std::
size_t NSD = num_space_dim>
711 KOKKOS_INLINE_FUNCTION std::enable_if_t<3 == NSD, Scalar>
723 template <
class Integer, std::
size_t NSD = num_space_dim>
724 KOKKOS_INLINE_FUNCTION std::enable_if_t<3 == NSD, Scalar>
736 template <
class Integer, std::
size_t NSD = num_space_dim>
737 KOKKOS_INLINE_FUNCTION std::enable_if_t<2 == NSD, Scalar>
740 return _local_edges[Dim::J][index[Dim::J] + 1] -
741 _local_edges[Dim::J][index[Dim::J]];
749 template <
class Integer, std::
size_t NSD = num_space_dim>
750 KOKKOS_INLINE_FUNCTION std::enable_if_t<2 == NSD, Scalar>
753 return _local_edges[Dim::I][index[Dim::I] + 1] -
754 _local_edges[Dim::I][index[Dim::I]];
762 template <
class Integer>
763 KOKKOS_INLINE_FUNCTION Scalar
768 m *= _local_edges[d][index[d] + 1] - _local_edges[d][index[d]];
773 Kokkos::Array<Scalar, num_space_dim> _own_low_corner;
774 Kokkos::Array<Scalar, num_space_dim> _own_high_corner;
775 Kokkos::Array<Scalar, num_space_dim> _ghost_low_corner;
776 Kokkos::Array<Scalar, num_space_dim> _ghost_high_corner;
777 Kokkos::Array<Kokkos::View<Scalar*, MemorySpace>, num_space_dim>
779 Kokkos::Array<bool, num_space_dim> _periodic;
780 Kokkos::Array<bool, num_space_dim> _boundary_lo;
781 Kokkos::Array<bool, num_space_dim> _boundary_hi;
789template <
class MemorySpace,
class MeshType>
790LocalMesh<MemorySpace, MeshType>
LocalMesh< MemorySpace, MeshType > createLocalMesh(const LocalGrid< MeshType > &local_grid)
Creation function for local mesh.
Definition Cabana_Grid_LocalMesh.hpp:791
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