GADGET-4
intposconvert.h
Go to the documentation of this file.
1/*******************************************************************************
2 * \copyright This file is part of the GADGET4 N-body/SPH code developed
3 * \copyright by Volker Springel. Copyright (C) 2014-2020 by Volker Springel
4 * \copyright (vspringel@mpa-garching.mpg.de) and all contributing authors.
5 *******************************************************************************/
6
12#ifndef CONVERT_H
13#define CONVERT_H
14
15#include "allvars.h"
16#include "dtypes.h"
17
18#include <cmath>
19
20#define MSB ((MyIntPosType)(~((MyIntPosType)(~((MyIntPosType)0)) >> ((MyIntPosType)1))))
21
22#if defined(LONG_X_BITS)
23#define HBITS_X ((MyIntPosType)(~((MyIntPosType)(~((MyIntPosType)0)) >> ((MyIntPosType)LONG_X_BITS))))
24#endif
25
26#if defined(LONG_Y_BITS)
27#define HBITS_Y ((MyIntPosType)(~((MyIntPosType)(~((MyIntPosType)0)) >> ((MyIntPosType)LONG_Y_BITS))))
28#endif
29
30#if defined(LONG_Z_BITS)
31#define HBITS_Z ((MyIntPosType)(~((MyIntPosType)(~((MyIntPosType)0)) >> ((MyIntPosType)LONG_Z_BITS))))
32#endif
33
35{
36 public:
40
41#ifndef PERIODIC
44#endif
45
46#ifdef RANDOMIZE_DOMAINCENTER
47 MyIntPosType CurrentShiftVector[3];
48#endif
49
50#ifdef EXPLICIT_VECTORIZATION
51 inline Vec4d nearest_image_intpos_to_doublepos_vectorial(MyIntPosType const &a, MyIntPosType const &b0, MyIntPosType const &b1,
52 MyIntPosType const &b2, MyIntPosType const &b3)
53 {
54#if defined(GRAVITY_TALLBOX) || defined(LONG_X_BITS) || defined(LONG_Y_BITS) || defined(LONG_Z_BITS)
55 Terminate("not working in this combination");
56#endif
57
58 Vec4MyIntPosType delta = a - Vec4MyIntPosType(b0, b1, b2, b3);
59
60 Vec4MySignedIntPosType intpos = (Vec4MySignedIntPosType)delta;
61
62 Vec4d pos = to_double(intpos);
63
64 return pos * FacIntToCoord;
65 }
66#endif
67
69 {
70#ifdef PERIODIC /* restrict the position to the primary range */
71
72#if defined(LONG_X_BITS)
73 pos[0] = (pos[0] << LONG_X_BITS) >> LONG_X_BITS;
74#endif
75
76#if defined(LONG_Y_BITS)
77 pos[1] = (pos[1] << LONG_Y_BITS) >> LONG_Y_BITS;
78#endif
79
80#if defined(LONG_Z_BITS)
81 pos[2] = (pos[2] << LONG_Z_BITS) >> LONG_Z_BITS;
82#endif
83
84#endif
85 }
86
87 /* function to determine the nearest periodic image distance vector in MyReal, exploiting integer wrap around */
88 template <typename T>
89 inline void diff_intpos_to_pos(MyIntPosType *a, MyIntPosType *b, T *posdiff, offset_tuple off = 0)
90 {
91 if(a[0] > b[0])
92 posdiff[0] = (a[0] - b[0]) * FacIntToCoord + All.BoxSize * off.n[0];
93 else
94 posdiff[0] = (b[0] - a[0]) * (-FacIntToCoord) + All.BoxSize * off.n[0];
95
96 if(a[1] > b[1])
97 posdiff[1] = (a[1] - b[1]) * FacIntToCoord + All.BoxSize * off.n[1];
98 else
99 posdiff[1] = (b[1] - a[1]) * (-FacIntToCoord) + All.BoxSize * off.n[1];
100
101 if(a[2] > b[2])
102 posdiff[2] = (a[2] - b[2]) * FacIntToCoord + All.BoxSize * off.n[2];
103 else
104 posdiff[2] = (b[2] - a[2]) * (-FacIntToCoord) + All.BoxSize * off.n[2];
105 }
106
108 {
109#if defined(LONG_X_BITS)
110 MyIntPosType delta = (a << LONG_X_BITS) - (b << LONG_X_BITS);
111
112 if(delta & MSB) /* tests MSB */
113 {
114 delta >>= LONG_X_BITS;
115 delta |= HBITS_X;
116 }
117 else
118 delta >>= LONG_X_BITS;
119
120 return delta;
121#else
122 return a - b;
123#endif
124 }
125
127 {
128#if defined(LONG_Y_BITS)
129 MyIntPosType delta = (a << LONG_Y_BITS) - (b << LONG_Y_BITS);
130
131 if(delta & MSB) /* tests MSB */
132 {
133 delta >>= LONG_Y_BITS;
134 delta |= HBITS_Y;
135 }
136 else
137 delta >>= LONG_Y_BITS;
138
139 return delta;
140#else
141 return a - b;
142#endif
143 }
144
146 {
147#if defined(LONG_Z_BITS)
148 MyIntPosType delta = (a << LONG_Z_BITS) - (b << LONG_Z_BITS);
149
150 if(delta & MSB) /* tests MSB */
151 {
152 delta >>= LONG_Z_BITS;
153 delta |= HBITS_Z;
154 }
155 else
156 delta >>= LONG_Z_BITS;
157
158 return delta;
159#else
160 return a - b;
161#endif
162 }
163
164 /* function to determine the nearest periodic image distance vector in T, exploiting integer wrap around */
165 template <typename T>
166 inline void nearest_image_intpos_to_pos(const MyIntPosType *const a, const MyIntPosType *const b, T *posdiff)
167 {
168 MyIntPosType delta[3];
169 MySignedIntPosType *intpos = (MySignedIntPosType *)delta;
170
171 /* we use all these casts here to prevent that implicit type promotions can mess this up for types shorter than int, such as
172 * unsigned char */
173
174#if defined(GRAVITY_TALLBOX) && (GRAVITY_TALLBOX == 0)
175 if(a[0] >= b[0])
176 {
177 delta[0] = a[0] - b[0];
178 posdiff[0] = delta[0] * FacIntToCoord;
179 }
180 else
181 {
182 delta[0] = b[0] - a[0];
183 posdiff[0] = delta[0] * (-FacIntToCoord);
184 }
185#else
186
187#if defined(LONG_X_BITS)
188 delta[0] = (a[0] << LONG_X_BITS) - (b[0] << LONG_X_BITS);
189
190 if(delta[0] & MSB) /* tests MSB */
191 {
192 delta[0] >>= LONG_X_BITS;
193 delta[0] |= HBITS_X;
194 }
195 else
196 delta[0] >>= LONG_X_BITS;
197#else
198 delta[0] = a[0] - b[0];
199#endif
200 posdiff[0] = intpos[0] * FacIntToCoord;
201
202#endif
203
206#if defined(GRAVITY_TALLBOX) && (GRAVITY_TALLBOX == 1)
207 if(a[1] >= b[1])
208 {
209 delta[1] = a[1] - b[1];
210 posdiff[1] = delta[1] * FacIntToCoord;
211 }
212 else
213 {
214 delta[1] = b[1] - a[1];
215 posdiff[1] = delta[1] * (-FacIntToCoord);
216 }
217#else
218
219#if defined(LONG_Y_BITS)
220 delta[1] = (a[1] << LONG_Y_BITS) - (b[1] << LONG_Y_BITS);
221
222 if(delta[1] & MSB) /* tests MSB */
223 {
224 delta[1] >>= LONG_Y_BITS;
225 delta[1] |= HBITS_Y;
226 }
227 else
228 delta[1] >>= LONG_Y_BITS;
229#else
230 delta[1] = a[1] - b[1];
231#endif
232
233 posdiff[1] = intpos[1] * FacIntToCoord;
234#endif
235
238#if defined(GRAVITY_TALLBOX) && (GRAVITY_TALLBOX == 2)
239 if(a[2] >= b[2])
240 {
241 delta[2] = a[2] - b[2];
242 posdiff[2] = delta[2] * FacIntToCoord;
243 }
244 else
245 {
246 delta[2] = b[2] - a[2];
247 posdiff[2] = delta[2] * (-FacIntToCoord);
248 }
249#else
250
251#if defined(LONG_Z_BITS)
252 delta[2] = (a[2] << LONG_Z_BITS) - (b[2] << LONG_Z_BITS);
253
254 if(delta[2] & MSB) /* tests MSB */
255 {
256 delta[2] >>= LONG_Z_BITS;
257 delta[2] |= HBITS_Z;
258 }
259 else
260 delta[2] >>= LONG_Z_BITS;
261#else
262 delta[2] = a[2] - b[2];
263#endif
264 posdiff[2] = intpos[2] * FacIntToCoord;
265
266#endif
267 }
268
270 {
271#if defined(LONG_X_BITS)
272 delta[0] = (a[0] << LONG_X_BITS) - (b[0] << LONG_X_BITS);
273
274 if(delta[0] & (~((~((MyIntPosType)0)) >> 1))) /* tests MSB */
275 {
276 delta[0] >>= LONG_X_BITS;
277 delta[0] |= (~((~((MyIntPosType)0)) >> LONG_X_BITS));
278 }
279 else
280 delta[0] >>= LONG_X_BITS;
281#else
282 delta[0] = a[0] - b[0];
283#endif
284
285#if defined(LONG_Y_BITS)
286 delta[1] = (a[1] << LONG_Y_BITS) - (b[1] << LONG_Y_BITS);
287
288 if(delta[1] & (~((~((MyIntPosType)0)) >> 1))) /* tests MSB */
289 {
290 delta[1] >>= LONG_Y_BITS;
291 delta[1] |= (~((~((MyIntPosType)0)) >> LONG_Y_BITS));
292 }
293 else
294 delta[1] >>= LONG_Y_BITS;
295#else
296 delta[1] = a[1] - b[1];
297#endif
298
299#if defined(LONG_Z_BITS)
300 delta[2] = (a[2] << LONG_Z_BITS) - (b[2] << LONG_Z_BITS);
301
302 if(delta[2] & (~((~((MyIntPosType)0)) >> 1))) /* tests MSB */
303 {
304 delta[2] >>= LONG_Z_BITS;
305 delta[2] |= (~((~((MyIntPosType)0)) >> LONG_Z_BITS));
306 }
307 else
308 delta[2] >>= LONG_Z_BITS;
309#else
310 delta[2] = a[2] - b[2];
311#endif
312
313 if(delta[0] & (~((~((MyIntPosType)0)) >> 1))) /* tests MSB, i.e. negative if interpreted as signed int */
314 delta[0] = -delta[0];
315
316 if(delta[1] & (~((~((MyIntPosType)0)) >> 1))) /* tests MSB, i.e. negative if interpreted as signed int */
317 delta[1] = -delta[1];
318
319 if(delta[2] & (~((~((MyIntPosType)0)) >> 1))) /* tests MSB, i.e. negative if interpreted as signed int */
320 delta[2] = -delta[2];
321 }
322
323#if defined(POSITIONS_IN_32BIT)
324 template <typename T>
326 {
327 return std::lrint(posdiff * FacCoordToInt);
328 }
329
330 template <typename T>
331 inline void pos_to_signedintpos(T *posdiff, MySignedIntPosType *intpos)
332 {
333 for(int j = 0; j < 3; j++)
334 intpos[j] = std::lrint(posdiff[j] * FacCoordToInt);
335 }
336#elif defined(POSITIONS_IN_64BIT)
337 template <typename T>
339 {
340 return std::llrint(posdiff * FacCoordToInt);
341 }
342
343 template <typename T>
344 inline void pos_to_signedintpos(T *posdiff, MySignedIntPosType *intpos)
345 {
346 for(int j = 0; j < 3; j++)
347 intpos[j] = std::llrint(posdiff[j] * FacCoordToInt);
348 }
349#else
350 template <typename T>
352 {
353 return static_cast<MySignedIntPosType>(posdiff * FacCoordToInt);
354 }
355
356 template <typename T>
357 inline void pos_to_signedintpos(T *posdiff, MySignedIntPosType *intpos)
358 {
359 for(int j = 0; j < 3; j++)
360 intpos[j] = static_cast<MySignedIntPosType>(posdiff[j] * FacCoordToInt);
361 }
362#endif
363
364 template <typename T>
365 inline void signedintpos_to_pos(MySignedIntPosType *intpos, T *pos)
366 {
367 for(int j = 0; j < 3; j++)
368 pos[j] = intpos[j] * FacIntToCoord;
369 }
370
372 {
373 double pos[3];
374 for(int j = 0; j < 3; j++)
375 pos[j] = intpos[j] * FacIntToCoord;
376 return sqrt(pos[0] * pos[0] + pos[1] * pos[1] + pos[2] * pos[2]);
377 }
378
379 template <typename T>
380 inline void intpos_to_pos(MyIntPosType *intpos, T *posdiff)
381 {
382#ifdef RANDOMIZE_DOMAINCENTER
383#ifdef PERIODIC
384 MyIntPosType xyz[3];
385 for(int j = 0; j < 3; j++)
386 xyz[j] = intpos[j] - CurrentShiftVector[j];
387 constrain_intpos(xyz);
388 for(int j = 0; j < 3; j++)
389 posdiff[j] = xyz[j] * FacIntToCoord;
390#else
391 for(int j = 0; j < 3; j++)
392 posdiff[j] = (intpos[j] - CurrentShiftVector[j]) * FacIntToCoord + RegionCorner[j];
393#endif
394#else
395#ifdef PERIODIC
396 for(int j = 0; j < 3; j++)
397 posdiff[j] = intpos[j] * FacIntToCoord;
398#else
399 for(int j = 0; j < 3; j++)
400 posdiff[j] = intpos[j] * FacIntToCoord + RegionCorner[j];
401#endif
402#endif
403 }
404
405 inline void intpos_to_intpos(MyIntPosType *intpos, MyIntPosType *xyz)
406 {
407#ifdef RANDOMIZE_DOMAINCENTER
408 for(int j = 0; j < 3; j++)
409 xyz[j] = intpos[j] - CurrentShiftVector[j];
410#else
411 for(int j = 0; j < 3; j++)
412 xyz[j] = intpos[j];
413#endif
414
415#ifdef PERIODIC
416 constrain_intpos(xyz);
417#else
418 Terminate("integer coordinate output not defined if PERIODIC is not no");
419#endif
420 }
421
422 template <typename T>
423 inline T constrain_pos(T pos)
424 {
425 int rep = 0;
426
427 while(pos < 0)
428 {
429 pos += ((T)(~((MyIntPosType)0)) + static_cast<T>(1.0));
430
431 rep++;
432 if(rep > MAXITER)
433 Terminate("rep > MAX_ITER");
434 }
435
436 while(pos >= ((T)(~((MyIntPosType)0)) + static_cast<T>(1.0)))
437 {
438 pos -= ((T)(~((MyIntPosType)0)) + static_cast<T>(1.0));
439
440 rep++;
441 if(rep > MAXITER)
442 Terminate("rep > MAX_ITER");
443 }
444
445 return pos;
446 }
447
448 template <typename T>
449 inline void pos_to_intpos(T *posdiff, MyIntPosType *intpos)
450 {
451#ifdef RANDOMIZE_DOMAINCENTER
452#ifdef PERIODIC
453 for(int j = 0; j < 3; j++)
454 {
455 intpos[j] = constrain_pos(posdiff[j] * FacCoordToInt);
456 intpos[j] += CurrentShiftVector[j];
457 }
458 constrain_intpos(intpos);
459#else
460 for(int j = 0; j < 3; j++)
461 {
462 intpos[j] = constrain_pos((posdiff[j] - RegionCorner[j]) * FacCoordToInt);
463 intpos[j] += CurrentShiftVector[j];
464 }
465#endif
466#else
467#ifdef PERIODIC
468 for(int j = 0; j < 3; j++)
469 intpos[j] = constrain_pos(posdiff[j] * FacCoordToInt);
470
471 constrain_intpos(intpos);
472#else
473 for(int j = 0; j < 3; j++)
474 intpos[j] = constrain_pos((posdiff[j] - RegionCorner[j]) * FacCoordToInt);
475#endif
476#endif
477 }
478};
479
480#endif
declares a structure for global parameters and variables.
global_data_all_processes All
Definition: main.cc:40
MyReal FacCoordToInt
Definition: intposconvert.h:38
void nearest_image_intpos_to_absolute_intdist(const MyIntPosType *a, const MyIntPosType *b, MyIntPosType *delta)
double signedintpos_to_distanceorigin(MySignedIntPosType *intpos)
void intpos_to_intpos(MyIntPosType *intpos, MyIntPosType *xyz)
void pos_to_intpos(T *posdiff, MyIntPosType *intpos)
void nearest_image_intpos_to_pos(const MyIntPosType *const a, const MyIntPosType *const b, T *posdiff)
void pos_to_signedintpos(T *posdiff, MySignedIntPosType *intpos)
MySignedIntPosType pos_to_signedintpos(T posdiff)
void diff_intpos_to_pos(MyIntPosType *a, MyIntPosType *b, T *posdiff, offset_tuple off=0)
Definition: intposconvert.h:89
MyIntPosType nearest_image_intpos_to_intpos_Y(const MyIntPosType a, const MyIntPosType b)
MyReal RegionLen
Definition: intposconvert.h:39
MyReal RegionCenter[3]
Definition: intposconvert.h:43
MyIntPosType nearest_image_intpos_to_intpos_Z(const MyIntPosType a, const MyIntPosType b)
void intpos_to_pos(MyIntPosType *intpos, T *posdiff)
MyIntPosType nearest_image_intpos_to_intpos_X(const MyIntPosType a, const MyIntPosType b)
MyReal RegionCorner[3]
Definition: intposconvert.h:42
T constrain_pos(T pos)
void signedintpos_to_pos(MySignedIntPosType *intpos, T *pos)
MyReal FacIntToCoord
Definition: intposconvert.h:37
void constrain_intpos(MyIntPosType *pos)
Definition: intposconvert.h:68
#define MAXITER
Definition: constants.h:305
defines some custom data types used by the code
uint32_t MyIntPosType
Definition: dtypes.h:35
int32_t MySignedIntPosType
Definition: dtypes.h:36
double MyReal
Definition: dtypes.h:82
#define MSB
Definition: intposconvert.h:20
#define Terminate(...)
Definition: macros.h:15
long lrint(half arg)
Definition: half.hpp:2999
expr sqrt(half arg)
Definition: half.hpp:2777