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 
68  inline void constrain_intpos(MyIntPosType *pos)
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>
338  inline MySignedIntPosType pos_to_signedintpos(T posdiff)
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>
351  inline MySignedIntPosType pos_to_signedintpos(T posdiff)
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:19
long lrint(half arg)
Definition: half.hpp:2999
expr sqrt(half arg)
Definition: half.hpp:2777