TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
ConstIJK_ptr.h
1/****************************************************************************
2* Copyright (c) 2025, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#ifndef ConstIJK_ptr_included
17#define ConstIJK_ptr_included
18
19#include <IJK_Field.h>
20
21enum class DIRECTION { X=0, Y=1, Z=2 };
22
23/*! @brief This class implements a accessor to IJK_Field values.
24 *
25 * It provides efficient access to center, left and right neighbours en i, j, and k directions
26 * and checks if i,j,k are within the bounds
27 *
28 */
29template <typename _TYPE_, typename _TYPE_ARRAY_>
31{
32public:
33 /*! @brief builds a pointer to field(i,j,k);
34 *
35 */
37 {
38 ptr_ = &field(i, j, k);
39 j_stride_ = field.j_stride();
40 k_stride_ = field.k_stride();
41#ifndef NDEBUG
42 const int ghost = field.ghost();
43 i_min_ = - ghost;
44 i_max_ = field.ni() + ghost;
45 j_min_ = - ghost;
46 j_max_ = field.nj() + ghost;
47 k_min_ = - ghost;
48 k_max_ = field.nk() + ghost;
49 i_ = i;
50 j_ = j;
51 k_ = k;
52#endif
53 }
54 /*! @brief increments the pointer by j_stride (eg, j = j+1)
55 *
56 */
57 void next_j()
58 {
59 ptr_ += j_stride_;
60#ifndef NDEBUG
61 j_++;
62 assert(j_ < j_max_);
63#endif
64 }
65 /*! @brief returns field(i+i_offset, j, k)
66 *
67 */
68 void get_center(int i_offset, _TYPE_ & center) const
69 {
70 assert(i_ + i_offset >= i_min_ && i_ + i_offset < i_max_);
71 center = ptr_[i_offset];
72 }
73
74 /*! @brief returns left=field(i+i_offset-1, j, k) and center=field(i+i_offset, j, k)
75 *
76 */
77 void get_left_center(DIRECTION _DIR_, int i_offset, _TYPE_ & left, _TYPE_ & center) const
78 {
79 if(_DIR_ == DIRECTION::X)
80 {
81 assert(i_ + i_offset > i_min_ && i_ + i_offset < i_max_);
82 left = ptr_[i_offset - 1];
83 center = ptr_[i_offset];
84 }
85 if(_DIR_ == DIRECTION::Y)
86 {
87 assert(i_ + i_offset >= i_min_ && i_ + i_offset < i_max_);
88 assert(j_ - 1 >= j_min_);
89 center = ptr_[i_offset];
90 left = ptr_[i_offset - j_stride_];
91 }
92 if(_DIR_ == DIRECTION::Z)
93 {
94 assert(i_ + i_offset >= i_min_ && i_ + i_offset < i_max_);
95 assert(k_ - 1 >= k_min_);
96 center = ptr_[i_offset];
97 left = ptr_[i_offset - k_stride_];
98 }
99 }
100
101 void get_center_right(DIRECTION _DIR_, int i_offset, _TYPE_ & center, _TYPE_ & right) const
102 {
103 if(_DIR_ == DIRECTION::X)
104 {
105 assert(i_ + i_offset >= i_min_ && i_ + i_offset + 1 < i_max_);
106 center = ptr_[i_offset];
107 right = ptr_[i_offset + 1];
108 }
109 if(_DIR_ == DIRECTION::Y)
110 {
111 assert(i_ + i_offset >= i_min_ && i_ + i_offset < i_max_);
112 assert(j_ >= j_min_ && j_ + 1 <= j_max_);
113 center = ptr_[i_offset];
114 right = ptr_[i_offset + j_stride_];
115 }
116 if(_DIR_ == DIRECTION::Z)
117 {
118 assert(i_ + i_offset >= i_min_ && i_ + i_offset < i_max_);
119 assert(k_ + 1 < k_max_);
120 center = ptr_[i_offset];
121 right = ptr_[i_offset + k_stride_];
122 }
123
124 }
125
126 void get_left_center_right(DIRECTION _DIR_, int i_offset, _TYPE_ & left, _TYPE_ & center, _TYPE_ & right) const
127 {
128 if(_DIR_ == DIRECTION::X)
129 {
130 assert(i_ + i_offset > i_min_ && i_ + i_offset + 1 < i_max_);
131 left = ptr_[i_offset - 1];
132 center = ptr_[i_offset];
133 right = ptr_[i_offset + 1];
134 }
135 if(_DIR_ == DIRECTION::Y)
136 {
137 assert(i_ + i_offset >= i_min_ && i_ + i_offset < i_max_);
138 assert(j_ - 1 >= j_min_ && j_ + 1 <= j_max_);
139 center = ptr_[i_offset];
140 left = ptr_[i_offset - j_stride_];
141 right = ptr_[i_offset + j_stride_];
142 }
143 if(_DIR_ == DIRECTION::Z)
144 {
145 assert(i_ + i_offset >= i_min_ && i_ + i_offset < i_max_);
146 assert(k_ - 1 >= k_min_ && k_ + 1 < k_max_);
147 center = ptr_[i_offset];
148 left = ptr_[i_offset - k_stride_];
149 right = ptr_[i_offset + k_stride_];
150 }
151
152 }
153
154 void get_leftleft_left_center_right(DIRECTION _DIR_, int i_offset, _TYPE_ & leftleft, _TYPE_ & left, _TYPE_ & center, _TYPE_ & right) const
155 {
156 if(_DIR_ == DIRECTION::X)
157 {
158 assert(i_ + i_offset - 2 >= i_min_ && i_ + i_offset + 1 < i_max_);
159 leftleft = ptr_[i_offset-2];
160 left = ptr_[i_offset-1];
161 center = ptr_[i_offset];
162 right = ptr_[i_offset+1];
163 }
164 if(_DIR_ == DIRECTION::Y)
165 {
166 assert(i_ + i_offset >= i_min_ && i_ + i_offset <= i_max_);
167 assert(j_ - 2 >= j_min_ && j_ + 1 < j_max_);
168 leftleft = ptr_[i_offset-2*j_stride_];
169 left = ptr_[i_offset-j_stride_];
170 center = ptr_[i_offset];
171 right = ptr_[i_offset+j_stride_];
172 }
173 if(_DIR_ == DIRECTION::Z)
174 {
175 assert(i_ + i_offset >= i_min_ && i_ + i_offset <= i_max_);
176 assert(k_ - 2 >= k_min_ && k_ + 1 < k_max_);
177 leftleft = ptr_[i_offset-2*k_stride_];
178 left = ptr_[i_offset-k_stride_];
179 center = ptr_[i_offset];
180 right = ptr_[i_offset+k_stride_];
181 }
182
183 }
184
185
186 void get_center(int i_offset, Simd_template<_TYPE_>& center) const
187 {
188 assert(i_ + i_offset >= i_min_ && i_ + i_offset < i_max_);
189 center = SimdGet(ptr_ + i_offset);
190 }
191
192 void get_left_center(DIRECTION _DIR_, int i_offset, Simd_template<_TYPE_>& left, Simd_template<_TYPE_>& center) const
193 {
194 if(_DIR_ == DIRECTION::X)
195 {
196 assert(i_ + i_offset - 1 >= i_min_ && i_ + i_offset < i_max_);
197 SimdGetLeftCenter(ptr_ + i_offset, left, center);
198 }
199 if(_DIR_ == DIRECTION::Y)
200 {
201 assert(i_ + i_offset >= i_min_ && i_ + i_offset < i_max_);
202 assert(j_ - 1 >= j_min_);
203 center = SimdGet(ptr_ + i_offset);
204 left = SimdGet(ptr_ + i_offset - j_stride_);
205 }
206
207 if(_DIR_ == DIRECTION::Z)
208 {
209 assert(i_ + i_offset >= i_min_ && i_ + i_offset < i_max_);
210 assert(k_ - 1 >= k_min_);
211 center = SimdGet(ptr_ + i_offset);
212 left = SimdGet(ptr_ + i_offset - k_stride_);
213 }
214 }
215
216
217 void get_center_right(DIRECTION _DIR_, int i_offset, Simd_template<_TYPE_>& center, Simd_template<_TYPE_>& right) const
218 {
219 if(_DIR_ == DIRECTION::X)
220 {
221 assert(i_ + i_offset >= i_min_ && i_ + i_offset + 1 < i_max_);
222 SimdGetCenterRight(ptr_ + i_offset, center, right);
223 }
224 if(_DIR_ == DIRECTION::Y)
225 {
226 assert(i_ + i_offset >= i_min_ && i_ + i_offset < i_max_);
227 assert(j_ + 1 <= j_max_);
228 center = SimdGet(ptr_ + i_offset);
229 right = SimdGet(ptr_ + i_offset + j_stride_);
230 }
231 if(_DIR_ == DIRECTION::Z)
232 {
233 assert(i_ + i_offset >= i_min_ && i_ + i_offset < i_max_);
234 assert(k_ + 1 <= k_max_);
235 center = SimdGet(ptr_ + i_offset);
236 right = SimdGet(ptr_ + i_offset + k_stride_);
237 }
238
239 }
240
241 void get_left_center_right(DIRECTION _DIR_, int i_offset, Simd_template<_TYPE_>& left, Simd_template<_TYPE_>& center, Simd_template<_TYPE_>& right) const
242 {
243 if(_DIR_ == DIRECTION::X)
244 {
245 assert(i_ + i_offset - 1 >= i_min_ && i_ + i_offset + 1 < i_max_);
246 SimdGetLeftCenterRight(ptr_ + i_offset, left, center, right);
247 }
248 if(_DIR_ == DIRECTION::Y)
249 {
250 assert(i_ + i_offset >= i_min_ && i_ + i_offset < i_max_);
251 assert(j_ - 1 >= j_min_ && j_ + 1 <= j_max_);
252 center = SimdGet(ptr_ + i_offset);
253 left = SimdGet(ptr_ + i_offset - j_stride_);
254 right = SimdGet(ptr_ + i_offset + j_stride_);
255 }
256 if(_DIR_ == DIRECTION::Z)
257 {
258 assert(i_ + i_offset >= i_min_ && i_ + i_offset < i_max_);
259 assert(k_ - 1 >= k_min_ && k_ + 1 <= k_max_);
260 center = SimdGet(ptr_ + i_offset);
261 left = SimdGet(ptr_ + i_offset - k_stride_);
262 right = SimdGet(ptr_ + i_offset + k_stride_);
263 }
264
265 }
266
267 void get_leftleft_left_center_right(DIRECTION _DIR_, int i_offset, Simd_template<_TYPE_>& leftleft, Simd_template<_TYPE_>& left, Simd_template<_TYPE_>& center, Simd_template<_TYPE_>& right) const
268 {
269 if(_DIR_ == DIRECTION::X)
270 {
271 assert(i_ + i_offset - 2 >= i_min_ && i_ + i_offset + 1 < i_max_);
272 SimdGetLeftleftLeftCenterRight(ptr_ + i_offset, leftleft, left, center, right);
273 }
274 if(_DIR_ == DIRECTION::Y)
275 {
276 assert(i_ + i_offset >= i_min_ && i_ + i_offset <= i_max_);
277 assert(j_ - 2 >= j_min_ && j_ + 1 < j_max_);
278 leftleft = SimdGet(ptr_ + i_offset - 2 * j_stride_);
279 left = SimdGet(ptr_ + i_offset - j_stride_);
280 center = SimdGet(ptr_ + i_offset);
281 right = SimdGet(ptr_ + i_offset + j_stride_);
282 }
283 if(_DIR_ == DIRECTION::Z)
284 {
285 assert(i_ + i_offset >= i_min_ && i_ + i_offset <= i_max_);
286 assert(k_ - 2 >= k_min_ && k_ + 1 < k_max_);
287 leftleft = SimdGet(ptr_ + i_offset - 2 * k_stride_);
288 left = SimdGet(ptr_ + i_offset - k_stride_);
289 center = SimdGet(ptr_ + i_offset);
290 right = SimdGet(ptr_ + i_offset + k_stride_);
291 }
292 }
293
294 void get_left_center_c1c2(DIRECTION _COMPO1_, DIRECTION _COMPO2_, int i_offset, Simd_template<_TYPE_>& leftc1_leftc2, Simd_template<_TYPE_>& leftc1_centerc2, Simd_template<_TYPE_>& centerc1_leftc2, Simd_template<_TYPE_>& centerc1_centerc2) const
295 {
296 if(_COMPO1_ != DIRECTION::X && _COMPO2_ != DIRECTION::X)
297 {
298 int stride1 = _COMPO1_ == DIRECTION::Y ? j_stride_ : k_stride_;
299 int stride2 = _COMPO2_ == DIRECTION::Y ? j_stride_ : k_stride_;
300 leftc1_leftc2 = SimdGet(ptr_ + i_offset - j_stride_ - k_stride_);
301 leftc1_centerc2 = SimdGet(ptr_ + i_offset - stride1);
302 centerc1_leftc2 = SimdGet(ptr_ + i_offset - stride2);
303 centerc1_centerc2 = SimdGet(ptr_ + i_offset);
304 }
305 else
306 {
307 if(_COMPO1_ == DIRECTION::X)
308 {
309 int stride = _COMPO2_ == DIRECTION::Y ? j_stride_ : k_stride_;
310 SimdGetLeftCenter(ptr_ + i_offset - stride, leftc1_leftc2, centerc1_leftc2);
311 SimdGetLeftCenter(ptr_ + i_offset, leftc1_centerc2, centerc1_centerc2);
312 }
313 else
314 {
315 int stride = _COMPO1_ == DIRECTION::Y ? j_stride_ : k_stride_;
316 SimdGetLeftCenter(ptr_ + i_offset - stride, leftc1_leftc2, leftc1_centerc2);
317 SimdGetLeftCenter(ptr_ + i_offset, centerc1_leftc2, centerc1_centerc2);
318 }
319 }
320 }
321
322protected:
323 const _TYPE_ *ptr_; // pointer to the current location inside the IJK_Field
324 int j_stride_; // local copy of field_.j_stride()
325 int k_stride_; // idem
326#ifndef NDEBUG
327 // legal bounds
329 // current location of ptr_
330 int i_, j_, k_;
331#endif
332
333private:
334 int get_stride(DIRECTION _COMPO_)
335 {
336 switch(_COMPO_)
337 {
338 case DIRECTION::Y:
339 return j_stride_;
340 case DIRECTION::Z:
341 return k_stride_;
342 default:
343 {
344 Cerr << "ConstIJK_ptr::get_stride compo x not allowed" << finl;
346 return 0;
347 }
348 }
349 }
350};
351
352using ConstIJK_float_ptr = ConstIJK_ptr<float, ArrOfFloat>;
353using ConstIJK_double_ptr = ConstIJK_ptr<double, ArrOfDouble>;
354
355#endif
This class implements a accessor to IJK_Field values.
void get_left_center_c1c2(DIRECTION _COMPO1_, DIRECTION _COMPO2_, int i_offset, Simd_template< _TYPE_ > &leftc1_leftc2, Simd_template< _TYPE_ > &leftc1_centerc2, Simd_template< _TYPE_ > &centerc1_leftc2, Simd_template< _TYPE_ > &centerc1_centerc2) const
void get_center(int i_offset, Simd_template< _TYPE_ > &center) const
ConstIJK_ptr(const IJK_Field_local_template< _TYPE_, _TYPE_ARRAY_ > &field, int i, int j, int k)
builds a pointer to field(i,j,k);
void get_left_center_right(DIRECTION _DIR_, int i_offset, Simd_template< _TYPE_ > &left, Simd_template< _TYPE_ > &center, Simd_template< _TYPE_ > &right) const
void get_center(int i_offset, _TYPE_ &center) const
returns field(i+i_offset, j, k)
void get_leftleft_left_center_right(DIRECTION _DIR_, int i_offset, _TYPE_ &leftleft, _TYPE_ &left, _TYPE_ &center, _TYPE_ &right) const
void get_leftleft_left_center_right(DIRECTION _DIR_, int i_offset, Simd_template< _TYPE_ > &leftleft, Simd_template< _TYPE_ > &left, Simd_template< _TYPE_ > &center, Simd_template< _TYPE_ > &right) const
void get_left_center_right(DIRECTION _DIR_, int i_offset, _TYPE_ &left, _TYPE_ &center, _TYPE_ &right) const
void next_j()
increments the pointer by j_stride (eg, j = j+1)
void get_left_center(DIRECTION _DIR_, int i_offset, Simd_template< _TYPE_ > &left, Simd_template< _TYPE_ > &center) const
void get_left_center(DIRECTION _DIR_, int i_offset, _TYPE_ &left, _TYPE_ &center) const
returns left=field(i+i_offset-1, j, k) and center=field(i+i_offset, j, k)
void get_center_right(DIRECTION _DIR_, int i_offset, _TYPE_ &center, _TYPE_ &right) const
void get_center_right(DIRECTION _DIR_, int i_offset, Simd_template< _TYPE_ > &center, Simd_template< _TYPE_ > &right) const
: This class describes a scalar field in an ijk box without any parallel information.
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
This class provides a generic access to simd operations on x86, x86 AMD and ARM architectures.