LoAdSG
celldimension.h
1#ifndef CELLDIMENSION_H
2#define CELLDIMENSION_H
3
4#include "../myAssert.h"
5#include "../indices/index.h"
6#include "MultiDepthHashCellStructure.h"
7
8#include <iostream>
9
10
11class Static_CellOneD {
12
13public:
14 inline static double coordinate(indexInteger index);
15
16
17 inline static indexInteger nextRight(indexInteger index, int level);
18
19 inline static indexInteger nextLeft(indexInteger index, int level);
20
21protected:
22
23
24 inline static int depth(indexInteger index);
25
26 inline static indexInteger father(const indexInteger index);
27
28 inline static indexInteger leftSon(const indexInteger index);
29
30 inline static indexInteger rightSon(const indexInteger index);
31
32 inline static indexInteger nextLeft(indexInteger index);
33 inline static indexInteger nextRight(indexInteger index);
34
37
38
39
40private:
41 inline static int internDepth(indexInteger index);
42};
43
44
45class CellOneD : private Static_CellOneD {
46public:
47
48
49
50
51 inline CellOneD(indexInteger ind) : index(ind) {};
52
53 inline int depth();
54
55
57
63 inline CellOneD nextLeft();
65
66 inline CellOneD nextRight();
68
74 inline CellOneD nextRightLevel(int level);
75
76
77 inline double coordinate();
78
79 indexInteger getInteger() const { return index; }
80
81
82
83private:
84 indexInteger index;
85
86};
87
88//---------
89#if __cplusplus >= 202002L
90inline int Static_CellOneD::depth(indexInteger index) {
91 return std::bit_width(index>>1);
92}
93#else
94
95// static int Static_IndexOneD::depth_orignal(indexInteger index) {
96// int de = 0;
97// while(index!=1) {
98// de = de + 1;
99// index = index >> 1;
100// }
101// return de;
102// }
103
104inline int Static_CellOneD::depth(indexInteger index) {
105 static_assert(sizeof(indexInteger) == 4,
106 "__builtin_clz only works for ints or compile with cpp20 support");
107 if(index==0) return 0;
108 return __builtin_clz(index) ^ 31;
109}
110#endif
111
112inline int CellOneD::depth() {
113 return Static_CellOneD::depth(index);
114}
115
116
117double Static_CellOneD::coordinate(indexInteger index) {
118/*
119 double co = 0.0;
120 while(index>0) {
121 co = co * 0.5;
122 if((index&1)==1) co = co + 1.0;
123 else co = co - 1.0;
124 index = index>>1;
125//cout << " co: " << co << endl;
126 }
127 return co;
128*/
129
130 if(index==0)return 0;
131 int d = depth(index);
132 //cout << d << endl;
133
134 double h = 1.0/double(POW2(d));
135 //cout << h << endl;
136 indexInteger n= subtractFirstBit(index);
137 //cout << n << endl;
138 return double(2*n+1)*h;
139
140
141}
142double CellOneD::coordinate() {
143 return Static_CellOneD::coordinate(index);
144}
145
146#if __cplusplus >= 202002L
147indexInteger Static_CellOneD::nextRight(indexInteger index) {
148
149 if(index==~(1<<(sizeof(index)*8-1))) return 0;
150 return index >> (std::countr_one(index)+1);
151}
152#else
153
154indexInteger Static_CellOneD::nextRight(indexInteger index) {
155
156 static_assert(sizeof(indexInteger) == 4,
157 "__builtin_ctz only works for ints or compile with cpp20 support");
158 unsigned inverted = ~index;
159 unsigned firstRight = __builtin_ctz(inverted);
160 return index >> (firstRight + 1 );
161}
162#endif
163
164CellOneD CellOneD::nextRight() {
165 return CellOneD(Static_CellOneD::nextRight(index));
166}
167
168#if __cplusplus >= 202002L
169indexInteger Static_IndexOneD::nextLeft(indexInteger index) {
170 if(index==(1<<(sizeof(index)*8-1)))
171 return 0;
172 return index >> (std::countr_zero(index)+1);
173}
174#else
175
176indexInteger Static_CellOneD::nextLeft(indexInteger index) {
177 static_assert(sizeof(indexInteger) == 4,
178 "__builtin_ctz only works for ints or compile with cpp20 support");
179 unsigned firstRight = __builtin_ctz(index);
180 return index >> (firstRight + 1 );
181
182}
183#endif
184CellOneD CellOneD::nextLeft() {
185 return CellOneD(Static_CellOneD::nextLeft(index));
186}
187
188inline int Static_CellOneD::internDepth(indexInteger index) {
189 if(index==0) return -1;
190 return (sizeof(index)<<3) - __builtin_clz(index) - 1;
191/* int de = 0;
192 while(index!=1) {
193 de = de + 1;
194 index = index >> 1;
195 }
196 return de;*/
197}
198
199
200indexInteger Static_CellOneD::nextRight(indexInteger index, int level) {
201 int myDepth = internDepth(index);
202
203 level = level - myDepth;
204 myAssert(level>=0);
205
206 if(level==0) return nextRight(index);
207 index = (index << 1) + 1;
208 for(int i=1;i<level;++i) {
209 index = index << 1;
210 }
211 return index;
212}
213
214indexInteger Static_CellOneD::nextLeft(indexInteger index, int level) {
215 int myDepth = depth(index);
216
217 level = level - myDepth;
218 myAssert(level>=0);
219
220 if(level==0) return nextLeft(index);
221 index = index << 1;
222 for(int i=1;i<level;++i) {
223 index = (index << 1) + 1;
224 }
225 return index;
226}
227
228
229CellOneD CellOneD::nextRightLevel(int level) {
230 indexInteger indexRight = Static_CellOneD::nextRight(index,level);
231 return CellOneD(Static_CellOneD::nextRight(indexRight,level));
232}
233
234
235class CellDimension : private Static_CellOneD {
236public:
237 inline CellDimension();
238
239
240 inline indexInteger getIndex(int d) const;
241
242 inline int getDepth(int d) const;
243
244 inline bool operator==(const CellDimension I) const;
245
246 inline double coordinate(int d) const;
247
248 inline CellDimension nextLeftLevel(int d, int level);
249
250 inline CellDimension nextRightLevel(int d, int level);
251
252 inline void replace(int d, indexInteger newIndex);
253 inline void replace(int d, CellOneD indRep);
254
255 inline void PrintCoordinates(){
256 for(int d=0; d<DimensionSparseGrid; d++){
257 cout << coordinate(d) << " " ;
258 }
259 };
260
261 inline double getLeftBoundary(int d){
262 return nextLeftLevel(d, getDepth(d)).coordinate(d);
263 }
264
265 inline double getRightBoundary(int d){
266 return nextRightLevel(d, getDepth(d)).coordinate(d);
267 }
268
269
270
271private:
272
273 inline CellDimension(const indexInteger index_org[DimensionSparseGrid]);
274
275 indexInteger index[DimensionSparseGrid];
276};
277
278
279CellDimension::CellDimension(){
280
281 for (int i = 0; i < DimensionSparseGrid; ++i) {
282 index[i] = 2; // center point
283 }
284
285
286};
287
288double CellDimension::coordinate(int d) const {
289 return Static_CellOneD::coordinate(index[d]);
290}
291
292
293indexInteger CellDimension::getIndex(int d) const {
294 assertDimension(d);
295 return index[d];
296}
297
298int CellDimension::getDepth(int d) const {
299 assertDimension(d);
300 return Static_CellOneD::depth(index[d]);
301}
302
303
304inline bool CellDimension::operator==(const CellDimension I) const {
305 for(int d=0;d<DimensionSparseGrid;++d) {
306 if(index[d] != I.index[d]) return false;
307 }
308 return true;
309}
310
311
312CellDimension CellDimension::nextLeftLevel(int d, int level){
313 assertDimension(d);
314
315 CellDimension back(index);
316
317 back.replace(d, Static_CellOneD::nextLeft(index[d],level));
318
319 return back;
320}
321
322CellDimension CellDimension::nextRightLevel(int d, int level){
323 assertDimension(d);
324
325 CellDimension back(index);
326
327 back.replace(d, Static_CellOneD::nextRight(index[d],level));
328
329 return back;
330}
331
332
333
334inline void CellDimension::replace(int d, indexInteger newIndex) {
335 index[d] = newIndex;
336}
337
338
339void CellDimension::replace(int d, CellOneD indRep) {
340 index[d] = indRep.getInteger();
341}
342
343
344CellDimension::CellDimension(const indexInteger index_org[DimensionSparseGrid]) {
345 for (int i = 0; i < DimensionSparseGrid; ++i) {
346 index[i] = index_org[i];
347 }
348};
349
350
351#endif