26template <MInt nDim,
typename FloatType,
typename IdType>
32template <
typename FloatType,
typename IdType>
33struct Impl<2, FloatType, IdType> {
34 static IdType
f(
const FloatType*
const coordinates,
const IdType level) {
36 const IdType nDim = 2;
41 std::array<FloatType, nDim> x;
42 std::copy_n(coordinates, nDim, x.begin());
45 for(IdType l = 0; l < level; l++) {
47 const IdType SX = x[0] < 0.5 ? 0 : 1;
48 const IdType SY = x[1] < 0.5 ? 0 : 1;
52 const IdType S0 = (1 - SX) * (1 - SY);
53 const IdType S12 = SY;
54 const IdType S3 = SX * (1 - SY);
59 const IdType multiplier =
IPOW2(nDim * (level - 1 - l));
62 index += ((1 + SX) * S12 + 3 * S3) * multiplier;
66 std::array<FloatType, nDim> transformed;
67 transformed[0] = 2.0 * x[1] * S0 + (2.0 * x[0] - SX) * S12 + (-2.0 * x[1] + 1.0) * S3;
68 transformed[1] = 2.0 * x[0] * S0 + (2.0 * x[1] - 1.0) * S12 + 2.0 * (-x[0] + 1.0) * S3;
79template <
typename FloatType,
typename IdType>
80struct Impl<3, FloatType, IdType> {
81 static IdType
f(
const FloatType*
const coordinates,
const IdType level) {
83 const IdType nDim = 3;
88 std::array<FloatType, nDim> x;
89 std::copy_n(coordinates, nDim, x.begin());
92 for(IdType l = 0; l < level; l++) {
94 const IdType SX = x[0] < 0.5 ? 0 : 1;
95 const IdType SY = x[1] < 0.5 ? 0 : 1;
96 const IdType SZ = x[2] < 0.5 ? 0 : 1;
100 const IdType S0 = (1 - SX) * (1 - SY) * (1 - SZ);
101 const IdType S12 = SY * (1 - SZ);
102 const IdType S34 = SX * (1 - SY);
103 const IdType S56 = SY * SZ;
104 const IdType S7 = (1 - SX) * (1 - SY) * SZ;
109 const IdType multiplier =
IPOW2(nDim * (level - 1 - l));
112 index += ((1 + SX) * S12 + (3 + SZ) * S34 + (6 - SX) * S56 + 7 * S7) * multiplier;
116 std::array<FloatType, nDim> transformed;
118 2.0 * x[0] * S0 + 2.0 * x[2] * S12 + (-2.0 * x[1] + 1.0) * S34 + 2.0 * (-x[2] + 1.0) * S56 + 2.0 * x[0] * S7;
119 transformed[1] = 2.0 * x[2] * S0 + (2.0 * x[1] - 1.0) * S12 + 2.0 * (-x[0] + 1.0) * S34 + (2.0 * x[1] - 1.0) * S56
120 + 2.0 * (-x[2] + 1.0) * S7;
121 transformed[2] = 2.0 * x[1] * S0 + (2.0 * x[0] - SX) * S12 + (2.0 * x[2] - SZ) * S34
122 + (-2.0 * x[0] + 1.0 + SX) * S56 + (-2.0 * x[1] + 1.0) * S7;
164template <MInt nDim,
typename FloatType,
typename IdType>
165IdType
index(
const FloatType*
const x,
const IdType level) {
167 ASSERT(level >= 0,
"Level must be at least zero");
171 ASSERT(nDim * level <= CHAR_BIT *
static_cast<IdType
>(
sizeof(IdType)) - 1,
"Integer overflow: level too large");
174 ASSERT(x[0] >= 0.0 && x[0] <= 1.0,
"Coordinate 0 out of bounds.");
175 ASSERT(x[1] >= 0.0 && x[1] <= 1.0,
"Coordinate 1 out of bounds.");
176 IF_CONSTEXPR(nDim == 3) { ASSERT(x[2] >= 0.0 && x[2] <= 1.0,
"Coordinate 2 out of bounds."); }
187template <MInt nDim,
typename FloatType,
typename IdType>
189 const FloatType*
const x,
191 const FloatType*
const centerOfGravity,
192 FloatType
const lengthOnLevel0) {
194 ASSERT(level >= 0,
"Level must be at least zero");
198 ASSERT(nDim * level <= CHAR_BIT *
static_cast<IdType
>(
sizeof(IdType)) - 1,
"Integer overflow: level too large");
202 for(IdType k = 0; k < nDim; k++) {
203 if(x[k] < centerOfGravity[k] - 0.5 * lengthOnLevel0 || x[k] > centerOfGravity[k] + 0.5 * lengthOnLevel0) {
208 treeId = std::numeric_limits<IdType>::is_signed ? -1 : ~0;
212 constexpr IdType id2 = (IdType)2;
213 for(IdType k = 0; k < nDim; k++) {
214 coord[k] = (IdType)((x[k] - centerOfGravity[k] + 0.5 * lengthOnLevel0) *
FPOW2(level) / lengthOnLevel0);
216 for(IdType lvl = level - 1; lvl >= 0; lvl--) {
217 for(IdType k = 0; k < nDim; k++) {
218 IdType bit = (coord[k] / (IdType)
IPOW2(lvl)) % id2;
219 treeId |= bit << bitCount;
231template <MInt nDim,
typename FloatType,
typename IdType>
235 const FloatType*
const centerOfGravity,
236 const FloatType lengthOnLevel0) {
238 ASSERT(level >= 0,
"Level must be at least zero");
242 ASSERT(nDim * level <= CHAR_BIT *
static_cast<IdType
>(
sizeof(IdType)) - 1,
"Integer overflow: level too large");
245 constexpr IdType id1 = (IdType)1;
246 for(IdType j = 0; j < nDim; j++) {
247 x[j] = centerOfGravity[j];
249 for(IdType lvl = 1; lvl <= level; lvl++) {
250 for(IdType j = 0; j < nDim; j++) {
251 IdType tmpBit = (treeId >> bitCount) & id1;
252 x[j] += (tmpBit ? 1.0 : -1.0) * lengthOnLevel0 *
FFPOW2(lvl + 1);
constexpr MLong IPOW2(MInt x)
constexpr MFloat FPOW2(MInt x)
constexpr MFloat FFPOW2(MInt x)
void treeIdToCoordinates(FloatType *const x, const IdType treeId, const IdType level, const FloatType *const centerOfGravity, const FloatType lengthOnLevel0)
IdType index(const FloatType *const x, const IdType level)
Return Hilbert index for given location and level in 2D or 3D.
MBool coordinatesToTreeId(IdType &treeId, const FloatType *const x, const IdType level, const FloatType *const centerOfGravity, FloatType const lengthOnLevel0)
Namespace for auxiliary functions/classes.
static IdType f(const FloatType *const coordinates, const IdType level)
static IdType f(const FloatType *const coordinates, const IdType level)