Block-Structured AMR Software Framework
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
AMReX_Morton.H
Go to the documentation of this file.
1#ifndef AMREX_MORTON_H_
2#define AMREX_MORTON_H_
3#include <AMReX_Config.H>
4
5#include <AMReX_REAL.H>
6#include <AMReX_Dim3.H>
7#include <AMReX_Array.H>
9
10#include <cstdint>
11
12namespace amrex::Morton {
13
31std::uint32_t makeSpace (std::uint32_t x) noexcept {
32#if (AMREX_SPACEDIM == 3)
33 // x : 0000,0000,0000,0000,0000,00a9,8765,4321
34 x = (x | (x << 16)) & 0x030000FF;
35 // x << 16 : 0000,00a9,8765,4321,0000,0000,0000,0000
36 // x | (x << 16): 0000,00a9,8765,4321,0000,00a9,8765,4321
37 // 0x030000FF : 0000,0011,0000,0000,0000,0000,1111,1111
38 // x : 0000,00a9,0000,0000,0000,0000,8765,4321
39 x = (x | (x << 8)) & 0x0300F00F;
40 // x << 8 : 0000,0000,0000,0000,8765,4321,0000,0000
41 // x | (x << 8) : 0000,00a9,0000,0000,8765,4321,8765,4321
42 // 0x0300F00F : 0000,0011,0000,0000,1111,0000,0000,1111
43 // x : 0000,00a9,0000,0000,8765,0000,0000,4321
44 x = (x | (x << 4)) & 0x030C30C3;
45 // x << 4 : 00a9,0000,0000,8765,0000,0000,4321,0000
46 // x | (x << 4) : 00a9,00a9,0000,8765,8765,0000,4321,4321
47 // 0x030C30C3 : 0000,0011,0000,1100,0011,0000,1100,0011
48 // x : 0000,00a9,0000,8700,0065,0000,4300,0021
49 x = (x | (x << 2)) & 0x09249249;
50 // x << 2 : 0000,a900,0087,0000,6500,0043,0000,2100
51 // x | (x << 2) : 0000,a9a9,0087,8700,6565,0043,4300,2121
52 // 0x09249249 : 0000,1001,0010,0100,1001,0010,0100,1001
53 // x : 0000,a009,0080,0700,6005,0040,0300,2001
54 return x;
55#elif (AMREX_SPACEDIM == 2)
56 // x : 0000,0000,0000,0000,gfed,cba9,8765,4321
57 x = (x | (x << 8)) & 0x00FF00FF;
58 // x << 8 : 0000,0000,gfed,cba9,8765,4321,0000,0000
59 // x | (x << 8): 0000,0000,gfed,cba9,????,????,8765,4321
60 // 0x00FF00FF : 0000,0000,1111,1111,0000,0000,1111,1111
61 // x : 0000,0000,gfed,cba9,0000,0000,8765,4321
62 x = (x | (x << 4)) & 0x0F0F0F0F;
63 // x << 4 : 0000,gfed,cba9,0000,0000,8765,4321,0000
64 // x | (x << 4): 0000,gfed,????,cba9,0000,8765,????,4321
65 // 0x0F0F0F0F : 0000,1111,0000,1111,0000,1111,0000,1111
66 // x : 0000,gfed,0000,cba9,0000,8765,0000,4321
67 x = (x | (x << 2)) & 0x33333333;
68 // x << 2 : 00gf,ed00,00cb,a900,0087,6500,0043,2100
69 // x | (x << 2): 00gf,??ed,00cb,??a9,0087,??65,0043,??21
70 // 0x33333333 : 0011,0011,0011,0011,0011,0011,0011,0011
71 // x : 00gf,00ed,00cb,00a9,0087,0065,0043,0021
72 x = (x | (x << 1)) & 0x55555555;
73 // x << 1 : 0gf0,0ed0,0cb0,0a90,0870,0650,0430,0210
74 // x | (x << 1): 0g?f,0e?d,0c?b,0a?9,08?7,06?5,04?3,02?1
75 // 0x55555555 : 0101,0101,0101,0101,0101,0101,0101,0101
76 // x : 0g0f,0e0d,0c0b,0a09,0807,0605,0403,0201
77 return x;
78#elif (AMREX_SPACEDIM == 1)
79 return x;
80#endif
81}
82
97std::uint32_t toUInt10 (amrex::Real x, amrex::Real xmin, amrex::Real xmax) noexcept {
98 AMREX_ASSERT(x >= xmin && x < xmax);
99 constexpr std::uint32_t code_offset = (1U << 10);
100 return (std::uint32_t)(((x - xmin)/(xmax - xmin)) * code_offset);
101}
102
117std::uint32_t toUInt16 (amrex::Real x, amrex::Real xmin, amrex::Real xmax) noexcept {
118 AMREX_ASSERT(x >= xmin && x < xmax);
119 constexpr std::uint32_t code_offset = (1U << 16);
120 return (std::uint32_t)(((x - xmin)/(xmax - xmin)) * code_offset);
121}
122
135std::uint32_t toUInt32 (amrex::Real x, amrex::Real xmin, amrex::Real xmax) noexcept {
136 AMREX_ASSERT(x >= xmin && x < xmax);
137 constexpr unsigned long long code_offset = (1ULL << 32);
138 return (std::uint32_t)(((x - xmin)/(xmax - xmin)) * Real(code_offset));
139}
140
158std::uint32_t get32BitCode (AMREX_D_DECL(Real x, Real y, Real z),
160 const GpuArray<amrex::Real,AMREX_SPACEDIM>& phi) noexcept {
161#if (AMREX_SPACEDIM == 3)
162 std::uint32_t a = toUInt10(x, plo[0], phi[0]);
163 std::uint32_t b = toUInt10(y, plo[1], phi[1]);
164 std::uint32_t c = toUInt10(z, plo[2], phi[2]);
165#elif (AMREX_SPACEDIM == 2)
166 std::uint32_t a = toUInt16(x, plo[0], phi[0]);
167 std::uint32_t b = toUInt16(y, plo[1], phi[1]);
168#elif (AMREX_SPACEDIM == 1)
169 std::uint32_t a = toUInt32(x, plo[0], phi[0]);
170#endif
171 return AMREX_D_TERM(makeSpace(a), | (makeSpace(b) << 1), | (makeSpace(c) << 2));
172}
173
185#if (AMREX_SPACEDIM == 3)
187std::uint32_t get32BitCode (const XDim3& p,
189 const GpuArray<amrex::Real,AMREX_SPACEDIM>& phi) noexcept {
190 return get32BitCode(p.x, p.y, p.z, plo, phi);
191}
192#endif
193
194}
195#endif
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:119
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
#define AMREX_D_TERM(a, b, c)
Definition AMReX_SPACE.H:129
Definition AMReX_Morton.H:12
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::uint32_t toUInt32(amrex::Real x, amrex::Real xmin, amrex::Real xmax) noexcept
Convert a Real to a uint32, keeping all significant bits. It is assumed that xmin <= x < xmax.
Definition AMReX_Morton.H:135
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::uint32_t toUInt16(amrex::Real x, amrex::Real xmin, amrex::Real xmax) noexcept
Convert a Real to a uint32, keeping only 16 significant bits. This puts the first 16 bits of x into r...
Definition AMReX_Morton.H:117
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::uint32_t makeSpace(std::uint32_t x) noexcept
This makes space in the input 32-bit integer by splitting the bits so they can be interleaved.
Definition AMReX_Morton.H:31
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::uint32_t get32BitCode(AMREX_D_DECL(Real x, Real y, Real z), const GpuArray< amrex::Real, AMREX_SPACEDIM > &plo, const GpuArray< amrex::Real, AMREX_SPACEDIM > &phi) noexcept
Given a 3D real-space coordinate, returns a Morton code stored in an unsigned 32 bit integer.
Definition AMReX_Morton.H:158
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::uint32_t toUInt10(amrex::Real x, amrex::Real xmin, amrex::Real xmax) noexcept
Convert a Real to a uint32, keeping only 10 significant bits. This puts the first 10 bits of x into r...
Definition AMReX_Morton.H:97
Definition AMReX_Array.H:34
Definition AMReX_Dim3.H:13