Cabana 0.8.0-dev
 
Loading...
Searching...
No Matches
Cabana_CartesianGrid.hpp
1/****************************************************************************
2 * Copyright (c) 2018-2023 by the Cabana authors *
3 * All rights reserved. *
4 * *
5 * This file is part of the Cabana library. Cabana is distributed under a *
6 * BSD 3-clause license. For the licensing terms see the LICENSE file in *
7 * the top-level directory. *
8 * *
9 * SPDX-License-Identifier: BSD-3-Clause *
10 ****************************************************************************/
11
12#ifndef CABANA_CARTESIANGRID_HPP
13#define CABANA_CARTESIANGRID_HPP
14
15#include <Kokkos_Core.hpp>
16
17#include <limits>
18#include <type_traits>
19
20namespace Cabana
21{
22namespace Impl
23{
25
26template <class Real, typename std::enable_if<
27 std::is_floating_point<Real>::value, int>::type = 0>
28class CartesianGrid
29{
30 public:
31 using real_type = Real;
32
33 Real _min_x;
34 Real _min_y;
35 Real _min_z;
36 Real _max_x;
37 Real _max_y;
38 Real _max_z;
39 Real _dx;
40 Real _dy;
41 Real _dz;
42 Real _rdx;
43 Real _rdy;
44 Real _rdz;
45 int _nx;
46 int _ny;
47 int _nz;
48
49 CartesianGrid() {}
50
51 CartesianGrid( const Real min_x, const Real min_y, const Real min_z,
52 const Real max_x, const Real max_y, const Real max_z,
53 const Real delta_x, const Real delta_y, const Real delta_z )
54 : _min_x( min_x )
55 , _min_y( min_y )
56 , _min_z( min_z )
57 , _max_x( max_x )
58 , _max_y( max_y )
59 , _max_z( max_z )
60 {
61 _nx = cellsBetween( max_x, min_x, 1.0 / delta_x );
62 _ny = cellsBetween( max_y, min_y, 1.0 / delta_y );
63 _nz = cellsBetween( max_z, min_z, 1.0 / delta_z );
64
65 _dx = ( max_x - min_x ) / _nx;
66 _dy = ( max_y - min_y ) / _ny;
67 _dz = ( max_z - min_z ) / _nz;
68
69 _rdx = 1.0 / _dx;
70 _rdy = 1.0 / _dy;
71 _rdz = 1.0 / _dz;
72 }
73
74 // Get the total number of cells.
75 KOKKOS_INLINE_FUNCTION
76 std::size_t totalNumCells() const { return _nx * _ny * _nz; }
77
78 // Get the number of cells in each direction.
79 KOKKOS_INLINE_FUNCTION
80 void numCells( int& num_x, int& num_y, int& num_z )
81 {
82 num_x = _nx;
83 num_y = _ny;
84 num_z = _nz;
85 }
86
87 // Get the number of cells in a given direction.
88 KOKKOS_INLINE_FUNCTION
89 int numBin( const int dim ) const
90 {
91 if ( 0 == dim )
92 return _nx;
93 else if ( 1 == dim )
94 return _ny;
95 else if ( 2 == dim )
96 return _nz;
97 else
98 return -1;
99 }
100
101 // Given a position get the ijk indices of the cell in which
102 KOKKOS_INLINE_FUNCTION
103 void locatePoint( const Real xp, const Real yp, const Real zp, int& ic,
104 int& jc, int& kc ) const
105 {
106 // Since we use a floor function a point on the outer boundary
107 // will be found in the next cell, causing an out of bounds error
108 ic = cellsBetween( xp, _min_x, _rdx );
109 ic = ( ic == _nx ) ? ic - 1 : ic;
110 jc = cellsBetween( yp, _min_y, _rdy );
111 jc = ( jc == _ny ) ? jc - 1 : jc;
112 kc = cellsBetween( zp, _min_z, _rdz );
113 kc = ( kc == _nz ) ? kc - 1 : kc;
114 }
115
116 // Given a position and a cell index get square of the minimum distance to
117 // that point to any point in the cell. If the point is in the cell the
118 // returned distance is zero.
119 KOKKOS_INLINE_FUNCTION
120 Real minDistanceToPoint( const Real xp, const Real yp, const Real zp,
121 const int ic, const int jc, const int kc ) const
122 {
123 Real xc = _min_x + ( ic + 0.5 ) * _dx;
124 Real yc = _min_y + ( jc + 0.5 ) * _dy;
125 Real zc = _min_z + ( kc + 0.5 ) * _dz;
126
127 Real rx = fabs( xp - xc ) - 0.5 * _dx;
128 Real ry = fabs( yp - yc ) - 0.5 * _dy;
129 Real rz = fabs( zp - zc ) - 0.5 * _dz;
130
131 rx = ( rx > 0.0 ) ? rx : 0.0;
132 ry = ( ry > 0.0 ) ? ry : 0.0;
133 rz = ( rz > 0.0 ) ? rz : 0.0;
134
135 return rx * rx + ry * ry + rz * rz;
136 }
137
138 // Given the ijk index of a cell get its cardinal index.
139 KOKKOS_INLINE_FUNCTION
140 int cardinalCellIndex( const int i, const int j, const int k ) const
141 {
142 return ( i * _ny + j ) * _nz + k;
143 }
144
145 KOKKOS_INLINE_FUNCTION
146 void ijkBinIndex( const int cardinal, int& i, int& j, int& k ) const
147 {
148 i = cardinal / ( _ny * _nz );
149 j = ( cardinal / _nz ) % _ny;
150 k = cardinal % _nz;
151 }
152
153 // Calculate the number of full cells between 2 points.
154 KOKKOS_INLINE_FUNCTION
155 int cellsBetween( const Real max, const Real min, const Real rdelta ) const
156 {
157 return Kokkos::floor( ( max - min ) * rdelta );
158 }
159};
160
162} // end namespace Impl
163} // end namespace Cabana
164
165#endif // end CABANA_CARTESIANGRID_HPP
Core: particle data structures and algorithms.
Definition Cabana_AoSoA.hpp:36