GADGET-4
peano.cc
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 #include "gadgetconfig.h"
13 
14 #include <math.h>
15 #include <mpi.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <algorithm>
20 
21 #include "../data/allvars.h"
22 #include "../data/dtypes.h"
23 #include "../data/mymalloc.h"
24 #include "../logs/timer.h"
25 #include "../main/simulation.h"
26 #include "../sort/cxxsort.h"
27 #include "../sort/peano.h"
28 #include "../system/system.h"
29 
30 namespace
31 {
32 struct peano_hilbert_data
33 {
34  peanokey key;
35  int index;
36 };
37 
38 /*
39 struct peano_comparator
40 {
41 bool operator() (const peano_hilbert_data & a, const peano_hilbert_data & b)
42 {
43  return a.key < b.key;
44 }
45 };
46 */
47 
48 const unsigned char rottable3[48][8] = {
49  {36, 28, 25, 27, 10, 10, 25, 27}, {29, 11, 24, 24, 37, 11, 26, 26}, {8, 8, 25, 27, 30, 38, 25, 27},
50  {9, 39, 24, 24, 9, 31, 26, 26}, {40, 24, 44, 32, 40, 6, 44, 6}, {25, 7, 33, 7, 41, 41, 45, 45},
51  {4, 42, 4, 46, 26, 42, 34, 46}, {43, 43, 47, 47, 5, 27, 5, 35}, {33, 35, 36, 28, 33, 35, 2, 2},
52  {32, 32, 29, 3, 34, 34, 37, 3}, {33, 35, 0, 0, 33, 35, 30, 38}, {32, 32, 1, 39, 34, 34, 1, 31},
53  {24, 42, 32, 46, 14, 42, 14, 46}, {43, 43, 47, 47, 25, 15, 33, 15}, {40, 12, 44, 12, 40, 26, 44, 34},
54  {13, 27, 13, 35, 41, 41, 45, 45}, {28, 41, 28, 22, 38, 43, 38, 22}, {42, 40, 23, 23, 29, 39, 29, 39},
55  {41, 36, 20, 36, 43, 30, 20, 30}, {37, 31, 37, 31, 42, 40, 21, 21}, {28, 18, 28, 45, 38, 18, 38, 47},
56  {19, 19, 46, 44, 29, 39, 29, 39}, {16, 36, 45, 36, 16, 30, 47, 30}, {37, 31, 37, 31, 17, 17, 46, 44},
57  {12, 4, 1, 3, 34, 34, 1, 3}, {5, 35, 0, 0, 13, 35, 2, 2}, {32, 32, 1, 3, 6, 14, 1, 3},
58  {33, 15, 0, 0, 33, 7, 2, 2}, {16, 0, 20, 8, 16, 30, 20, 30}, {1, 31, 9, 31, 17, 17, 21, 21},
59  {28, 18, 28, 22, 2, 18, 10, 22}, {19, 19, 23, 23, 29, 3, 29, 11}, {9, 11, 12, 4, 9, 11, 26, 26},
60  {8, 8, 5, 27, 10, 10, 13, 27}, {9, 11, 24, 24, 9, 11, 6, 14}, {8, 8, 25, 15, 10, 10, 25, 7},
61  {0, 18, 8, 22, 38, 18, 38, 22}, {19, 19, 23, 23, 1, 39, 9, 39}, {16, 36, 20, 36, 16, 2, 20, 10},
62  {37, 3, 37, 11, 17, 17, 21, 21}, {4, 17, 4, 46, 14, 19, 14, 46}, {18, 16, 47, 47, 5, 15, 5, 15},
63  {17, 12, 44, 12, 19, 6, 44, 6}, {13, 7, 13, 7, 18, 16, 45, 45}, {4, 42, 4, 21, 14, 42, 14, 23},
64  {43, 43, 22, 20, 5, 15, 5, 15}, {40, 12, 21, 12, 40, 6, 23, 6}, {13, 7, 13, 7, 41, 41, 22, 20}};
65 
66 const unsigned char subpix3[48][8] = {
67  {0, 7, 1, 6, 3, 4, 2, 5}, {7, 4, 6, 5, 0, 3, 1, 2}, {4, 3, 5, 2, 7, 0, 6, 1}, {3, 0, 2, 1, 4, 7, 5, 6}, {1, 0, 6, 7, 2, 3, 5, 4},
68  {0, 3, 7, 4, 1, 2, 6, 5}, {3, 2, 4, 5, 0, 1, 7, 6}, {2, 1, 5, 6, 3, 0, 4, 7}, {6, 1, 7, 0, 5, 2, 4, 3}, {1, 2, 0, 3, 6, 5, 7, 4},
69  {2, 5, 3, 4, 1, 6, 0, 7}, {5, 6, 4, 7, 2, 1, 3, 0}, {7, 6, 0, 1, 4, 5, 3, 2}, {6, 5, 1, 2, 7, 4, 0, 3}, {5, 4, 2, 3, 6, 7, 1, 0},
70  {4, 7, 3, 0, 5, 6, 2, 1}, {6, 7, 5, 4, 1, 0, 2, 3}, {7, 0, 4, 3, 6, 1, 5, 2}, {0, 1, 3, 2, 7, 6, 4, 5}, {1, 6, 2, 5, 0, 7, 3, 4},
71  {2, 3, 1, 0, 5, 4, 6, 7}, {3, 4, 0, 7, 2, 5, 1, 6}, {4, 5, 7, 6, 3, 2, 0, 1}, {5, 2, 6, 1, 4, 3, 7, 0}, {7, 0, 6, 1, 4, 3, 5, 2},
72  {0, 3, 1, 2, 7, 4, 6, 5}, {3, 4, 2, 5, 0, 7, 1, 6}, {4, 7, 5, 6, 3, 0, 2, 1}, {6, 7, 1, 0, 5, 4, 2, 3}, {7, 4, 0, 3, 6, 5, 1, 2},
73  {4, 5, 3, 2, 7, 6, 0, 1}, {5, 6, 2, 1, 4, 7, 3, 0}, {1, 6, 0, 7, 2, 5, 3, 4}, {6, 5, 7, 4, 1, 2, 0, 3}, {5, 2, 4, 3, 6, 1, 7, 0},
74  {2, 1, 3, 0, 5, 6, 4, 7}, {0, 1, 7, 6, 3, 2, 4, 5}, {1, 2, 6, 5, 0, 3, 7, 4}, {2, 3, 5, 4, 1, 0, 6, 7}, {3, 0, 4, 7, 2, 1, 5, 6},
75  {1, 0, 2, 3, 6, 7, 5, 4}, {0, 7, 3, 4, 1, 6, 2, 5}, {7, 6, 4, 5, 0, 1, 3, 2}, {6, 1, 5, 2, 7, 0, 4, 3}, {5, 4, 6, 7, 2, 3, 1, 0},
76  {4, 3, 7, 0, 5, 2, 6, 1}, {3, 2, 0, 1, 4, 5, 7, 6}, {2, 5, 1, 6, 3, 4, 0, 7}};
77 
78 } // unnamed namespace
79 
84 {
85  unsigned char rotation = 0;
86  peanokey key = {0, 0, 0};
87 
88  for(MyIntPosType mask = ((MyIntPosType)1) << (bits - 1); mask > 0; mask >>= 1)
89  {
90  unsigned char pix = ((x & mask) ? 4 : 0) | ((y & mask) ? 2 : 0) | ((z & mask) ? 1 : 0);
91 
92  key.hs <<= 3;
93  key.hs |= (key.is & (~((~((MyIntPosType)0)) >> 3))) >> (BITS_FOR_POSITIONS - 3);
94 
95  key.is <<= 3;
96  key.is |= (key.ls & (~((~((MyIntPosType)0)) >> 3))) >> (BITS_FOR_POSITIONS - 3);
97 
98  key.ls <<= 3;
99  key.ls |= subpix3[rotation][pix];
100 
101  rotation = rottable3[rotation][pix];
102  }
103 
104  return key;
105 }
106 
107 unsigned char peano_incremental_key(unsigned char pix, unsigned char *rotation)
108 {
109  unsigned char outpix = subpix3[*rotation][pix];
110  *rotation = rottable3[*rotation][pix];
111 
112  return outpix;
113 }
114 
115 const unsigned char irottable3[48][8] = {
116  {28, 27, 27, 10, 10, 25, 25, 36}, {29, 24, 24, 11, 11, 26, 26, 37}, {30, 25, 25, 8, 8, 27, 27, 38},
117  {31, 26, 26, 9, 9, 24, 24, 39}, {32, 44, 44, 6, 6, 40, 40, 24}, {33, 45, 45, 7, 7, 41, 41, 25},
118  {34, 46, 46, 4, 4, 42, 42, 26}, {35, 47, 47, 5, 5, 43, 43, 27}, {36, 33, 33, 2, 2, 35, 35, 28},
119  {37, 34, 34, 3, 3, 32, 32, 29}, {38, 35, 35, 0, 0, 33, 33, 30}, {39, 32, 32, 1, 1, 34, 34, 31},
120  {24, 42, 42, 14, 14, 46, 46, 32}, {25, 43, 43, 15, 15, 47, 47, 33}, {26, 40, 40, 12, 12, 44, 44, 34},
121  {27, 41, 41, 13, 13, 45, 45, 35}, {41, 28, 28, 22, 22, 38, 38, 43}, {42, 29, 29, 23, 23, 39, 39, 40},
122  {43, 30, 30, 20, 20, 36, 36, 41}, {40, 31, 31, 21, 21, 37, 37, 42}, {47, 38, 38, 18, 18, 28, 28, 45},
123  {44, 39, 39, 19, 19, 29, 29, 46}, {45, 36, 36, 16, 16, 30, 30, 47}, {46, 37, 37, 17, 17, 31, 31, 44},
124  {12, 1, 1, 34, 34, 3, 3, 4}, {13, 2, 2, 35, 35, 0, 0, 5}, {14, 3, 3, 32, 32, 1, 1, 6},
125  {15, 0, 0, 33, 33, 2, 2, 7}, {0, 16, 16, 30, 30, 20, 20, 8}, {1, 17, 17, 31, 31, 21, 21, 9},
126  {2, 18, 18, 28, 28, 22, 22, 10}, {3, 19, 19, 29, 29, 23, 23, 11}, {4, 11, 11, 26, 26, 9, 9, 12},
127  {5, 8, 8, 27, 27, 10, 10, 13}, {6, 9, 9, 24, 24, 11, 11, 14}, {7, 10, 10, 25, 25, 8, 8, 15},
128  {8, 22, 22, 38, 38, 18, 18, 0}, {9, 23, 23, 39, 39, 19, 19, 1}, {10, 20, 20, 36, 36, 16, 16, 2},
129  {11, 21, 21, 37, 37, 17, 17, 3}, {19, 14, 14, 46, 46, 4, 4, 17}, {16, 15, 15, 47, 47, 5, 5, 18},
130  {17, 12, 12, 44, 44, 6, 6, 19}, {18, 13, 13, 45, 45, 7, 7, 16}, {21, 4, 4, 42, 42, 14, 14, 23},
131  {22, 5, 5, 43, 43, 15, 15, 20}, {23, 6, 6, 40, 40, 12, 12, 21}, {20, 7, 7, 41, 41, 13, 13, 22}};
132 
133 const unsigned char ipixtable3[48][8] = {
134  {1, 3, 7, 5, 4, 6, 2, 0}, {0, 2, 3, 1, 5, 7, 6, 4}, {4, 6, 2, 0, 1, 3, 7, 5}, {5, 7, 6, 4, 0, 2, 3, 1}, {3, 2, 6, 7, 5, 4, 0, 1},
135  {2, 6, 7, 3, 1, 5, 4, 0}, {6, 7, 3, 2, 0, 1, 5, 4}, {7, 3, 2, 6, 4, 0, 1, 5}, {2, 0, 4, 6, 7, 5, 1, 3}, {6, 4, 5, 7, 3, 1, 0, 2},
136  {7, 5, 1, 3, 2, 0, 4, 6}, {3, 1, 0, 2, 6, 4, 5, 7}, {0, 1, 5, 4, 6, 7, 3, 2}, {4, 0, 1, 5, 7, 3, 2, 6}, {5, 4, 0, 1, 3, 2, 6, 7},
137  {1, 5, 4, 0, 2, 6, 7, 3}, {1, 0, 2, 3, 7, 6, 4, 5}, {0, 4, 6, 2, 3, 7, 5, 1}, {4, 5, 7, 6, 2, 3, 1, 0}, {5, 1, 3, 7, 6, 2, 0, 4},
138  {7, 6, 4, 5, 1, 0, 2, 3}, {3, 7, 5, 1, 0, 4, 6, 2}, {2, 3, 1, 0, 4, 5, 7, 6}, {6, 2, 0, 4, 5, 1, 3, 7}, {0, 2, 6, 4, 5, 7, 3, 1},
139  {4, 6, 7, 5, 1, 3, 2, 0}, {5, 7, 3, 1, 0, 2, 6, 4}, {1, 3, 2, 0, 4, 6, 7, 5}, {1, 0, 4, 5, 7, 6, 2, 3}, {0, 4, 5, 1, 3, 7, 6, 2},
140  {4, 5, 1, 0, 2, 3, 7, 6}, {5, 1, 0, 4, 6, 2, 3, 7}, {3, 1, 5, 7, 6, 4, 0, 2}, {2, 0, 1, 3, 7, 5, 4, 6}, {6, 4, 0, 2, 3, 1, 5, 7},
141  {7, 5, 4, 6, 2, 0, 1, 3}, {2, 3, 7, 6, 4, 5, 1, 0}, {6, 2, 3, 7, 5, 1, 0, 4}, {7, 6, 2, 3, 1, 0, 4, 5}, {3, 7, 6, 2, 0, 4, 5, 1},
142  {5, 4, 6, 7, 3, 2, 0, 1}, {1, 5, 7, 3, 2, 6, 4, 0}, {0, 1, 3, 2, 6, 7, 5, 4}, {4, 0, 2, 6, 7, 3, 1, 5}, {3, 2, 0, 1, 5, 4, 6, 7},
143  {2, 6, 4, 0, 1, 5, 7, 3}, {6, 7, 5, 4, 0, 1, 3, 2}, {7, 3, 1, 5, 4, 0, 2, 6},
144 };
145 
147 {
148  for(int i = bits; i < BITS_FOR_POSITIONS; i++)
149  {
150  key.hs <<= 3;
151  key.hs |= (key.is & (~((~((MyIntPosType)0)) >> 3))) >> (BITS_FOR_POSITIONS - 3);
152 
153  key.is <<= 3;
154  key.is |= (key.ls & (~((~((MyIntPosType)0)) >> 3))) >> (BITS_FOR_POSITIONS - 3);
155 
156  key.ls <<= 3;
157  }
158 
159  int rot = 24;
160 
161  *x = *y = *z = 0;
162 
163  for(int i = 0; i < bits; i++)
164  {
165  unsigned int keypart = (key.hs & (~((~((MyIntPosType)0)) >> 3))) >> (BITS_FOR_POSITIONS - 3);
166 
167  int quad = ipixtable3[rot][keypart];
168 
169  *x = (*x << 1) + (quad >> 2);
170  *y = (*y << 1) + ((quad & 2) >> 1);
171  *z = (*z << 1) + (quad & 1);
172  rot = irottable3[rot][keypart];
173 
174  key.hs <<= 3;
175  key.hs |= (key.is & (~((~((MyIntPosType)0)) >> 3))) >> (BITS_FOR_POSITIONS - 3);
176 
177  key.is <<= 3;
178  key.is |= (key.ls & (~((~((MyIntPosType)0)) >> 3))) >> (BITS_FOR_POSITIONS - 3);
179 
180  key.ls <<= 3;
181  }
182 }
MyIntPosType hs
Definition: dtypes.h:210
MyIntPosType is
Definition: dtypes.h:210
MyIntPosType ls
Definition: dtypes.h:210
uint32_t MyIntPosType
Definition: dtypes.h:35
#define BITS_FOR_POSITIONS
Definition: dtypes.h:37
void peano_hilbert_key_inverse(peanokey key, int bits, MyIntPosType *x, MyIntPosType *y, MyIntPosType *z)
Definition: peano.cc:146
unsigned char peano_incremental_key(unsigned char pix, unsigned char *rotation)
Definition: peano.cc:107
peanokey peano_hilbert_key(MyIntPosType x, MyIntPosType y, MyIntPosType z, int bits)
Definition: peano.cc:83
const unsigned char irottable3[48][8]
Definition: peano.cc:115
const unsigned char ipixtable3[48][8]
Definition: peano.cc:133