12#ifndef CABANA_CARTESIANGRID_HPP
13#define CABANA_CARTESIANGRID_HPP
15#include <Kokkos_Core.hpp>
26template <
class Real, std::
size_t NumSpaceDim = 3>
29 static_assert( std::is_floating_point<Real>::value,
30 "Scalar type must be floating point type." );
33 using real_type = Real;
34 static constexpr std::size_t num_space_dim = NumSpaceDim;
36 Kokkos::Array<real_type, num_space_dim> _min;
37 Kokkos::Array<real_type, num_space_dim> _max;
38 Kokkos::Array<real_type, num_space_dim> _dx;
39 Kokkos::Array<real_type, num_space_dim> _rdx;
40 Kokkos::Array<int, num_space_dim> _nx;
42 CartesianGrid() =
default;
44 template <
class ArrayType>
45 CartesianGrid(
const ArrayType min,
const ArrayType max,
46 const real_type delta_x )
48 Kokkos::Array<real_type, num_space_dim> delta;
49 for ( std::size_t d = 0; d < num_space_dim; ++d )
51 init( min, max, delta );
54 template <
class ArrayType>
55 CartesianGrid(
const ArrayType min,
const ArrayType max,
56 const ArrayType delta )
58 init( min, max, delta );
61 template <
class ArrayType,
class DeltaArrayType>
62 void init(
const ArrayType min,
const ArrayType max,
63 const DeltaArrayType delta )
65 for ( std::size_t d = 0; d < num_space_dim; ++d )
69 _nx[d] = cellsBetween( max[d], min[d], 1.0 / delta[d] );
70 _dx[d] = ( max[d] - min[d] ) / _nx[d];
71 _rdx[d] = 1.0 / _dx[d];
75 template <std::
size_t NSD = num_space_dim>
76 CartesianGrid(
const Real min_x,
const Real min_y,
const Real min_z,
77 const Real max_x,
const Real max_y,
const Real max_z,
78 const Real delta_x,
const Real delta_y,
const Real delta_z,
79 typename std::enable_if<NSD == 3, int>::type* = 0 )
80 : _min( { min_x, min_y, min_z } )
81 , _max( { max_x, max_y, max_z } )
83 _nx[0] = cellsBetween( max_x, min_x, 1.0 / delta_x );
84 _nx[1] = cellsBetween( max_y, min_y, 1.0 / delta_y );
85 _nx[2] = cellsBetween( max_z, min_z, 1.0 / delta_z );
87 _dx[0] = ( max_x - min_x ) / _nx[0];
88 _dx[1] = ( max_y - min_y ) / _nx[1];
89 _dx[2] = ( max_z - min_z ) / _nx[2];
91 _rdx[0] = 1.0 / _dx[0];
92 _rdx[1] = 1.0 / _dx[1];
93 _rdx[2] = 1.0 / _dx[2];
97 KOKKOS_INLINE_FUNCTION
98 std::size_t totalNumCells()
const
100 std::size_t total = 1;
101 for ( std::size_t d = 0; d < num_space_dim; ++d )
107 template <std::
size_t NSD = num_space_dim>
108 KOKKOS_INLINE_FUNCTION std::enable_if_t<3 == NSD, void>
109 numCells(
int& num_x,
int& num_y,
int& num_z )
117 template <std::
size_t NSD = num_space_dim>
118 KOKKOS_INLINE_FUNCTION std::enable_if_t<2 == NSD, void>
119 numCells(
int& num_x,
int& num_y )
126 KOKKOS_INLINE_FUNCTION
127 int numBin(
const int dim )
const
129 assert(
static_cast<std::size_t
>( dim ) < num_space_dim );
142 template <std::
size_t NSD = num_space_dim>
143 KOKKOS_INLINE_FUNCTION std::enable_if_t<3 == NSD, void>
144 locatePoint(
const Real xp,
const Real yp,
const Real zp,
int& ic,
int& jc,
149 ic = cellsBetween( xp, _min[0], _rdx[0] );
150 ic = ( ic == _nx[0] ) ? ic - 1 : ic;
151 jc = cellsBetween( yp, _min[1], _rdx[1] );
152 jc = ( jc == _nx[1] ) ? jc - 1 : jc;
153 kc = cellsBetween( zp, _min[2], _rdx[2] );
154 kc = ( kc == _nx[2] ) ? kc - 1 : kc;
158 template <std::
size_t NSD = num_space_dim>
159 KOKKOS_INLINE_FUNCTION std::enable_if_t<2 == NSD, void>
160 locatePoint(
const Real xp,
const Real yp,
int& ic,
int& jc )
const
164 ic = cellsBetween( xp, _min[0], _rdx[0] );
165 ic = ( ic == _nx[0] ) ? ic - 1 : ic;
166 jc = cellsBetween( yp, _min[1], _rdx[1] );
167 jc = ( jc == _nx[1] ) ? jc - 1 : jc;
171 KOKKOS_INLINE_FUNCTION
void
172 locatePoint(
const Kokkos::Array<Real, num_space_dim> p,
173 Kokkos::Array<int, num_space_dim>& c )
const
177 for ( std::size_t d = 0; d < num_space_dim; ++d )
179 c[d] = cellsBetween( p[d], _min[d], _rdx[d] );
180 c[d] = ( c[d] == _nx[d] ) ? c[d] - 1 : c[d];
187 template <std::
size_t NSD = num_space_dim>
188 KOKKOS_INLINE_FUNCTION std::enable_if_t<3 == NSD, Real>
189 minDistanceToPoint(
const Real xp,
const Real yp,
const Real zp,
190 const int ic,
const int jc,
const int kc )
const
192 Kokkos::Array<Real, num_space_dim> x;
196 Kokkos::Array<int, num_space_dim> c;
201 return minDistanceToPoint( x, c );
207 KOKKOS_INLINE_FUNCTION Real
208 minDistanceToPoint(
const Kokkos::Array<Real, num_space_dim> x,
209 const Kokkos::Array<int, num_space_dim> c )
const
212 for ( std::size_t d = 0; d < num_space_dim; ++d )
214 Real xc = _min[d] + ( c[d] + 0.5 ) * _dx[d];
215 Real rx = fabs( x[d] - xc ) - 0.5 * _dx[d];
217 rx = ( rx > 0.0 ) ? rx : 0.0;
226 template <std::
size_t NSD = num_space_dim>
227 KOKKOS_INLINE_FUNCTION std::enable_if_t<3 == NSD, int>
228 cardinalCellIndex(
const int i,
const int j,
const int k )
const
230 return ( i * _nx[1] + j ) * _nx[2] + k;
234 template <std::
size_t NSD = num_space_dim>
235 KOKKOS_INLINE_FUNCTION std::enable_if_t<2 == NSD, int>
236 cardinalCellIndex(
const int i,
const int j )
const
238 return i * _nx[1] + j;
242 KOKKOS_INLINE_FUNCTION
int
243 cardinalCellIndex(
const Kokkos::Array<int, num_space_dim> ijk )
const
245 if constexpr ( num_space_dim == 3 )
246 return cardinalCellIndex( ijk[0], ijk[1], ijk[2] );
248 return cardinalCellIndex( ijk[0], ijk[1] );
251 template <std::
size_t NSD = num_space_dim>
252 KOKKOS_INLINE_FUNCTION std::enable_if_t<3 == NSD, void>
253 ijkBinIndex(
const int cardinal,
int& i,
int& j,
int& k )
const
255 i = cardinal / ( _nx[1] * _nx[2] );
256 j = ( cardinal / _nx[2] ) % _nx[1];
257 k = cardinal % _nx[2];
260 template <std::
size_t NSD = num_space_dim>
261 KOKKOS_INLINE_FUNCTION std::enable_if_t<2 == NSD, void>
262 ijkBinIndex(
const int cardinal,
int& i,
int& j )
const
264 i = cardinal / ( _nx[1] );
265 j = cardinal % _nx[1];
268 KOKKOS_INLINE_FUNCTION
void
269 ijkBinIndex(
const int cardinal,
270 Kokkos::Array<int, num_space_dim>& ijk )
const
272 if constexpr ( num_space_dim == 3 )
273 return ijkBinIndex( cardinal, ijk[0], ijk[1], ijk[2] );
275 return ijkBinIndex( cardinal, ijk[0], ijk[1] );
279 KOKKOS_INLINE_FUNCTION
280 int cellsBetween(
const Real max,
const Real min,
const Real rdelta )
const
282 return Kokkos::floor( ( max - min ) * rdelta );
Core: particle data structures and algorithms.
Definition Cabana_AoSoA.hpp:36