1 #ifndef OMEGA_H_ALIGN_HPP
2 #define OMEGA_H_ALIGN_HPP
4 #include <Omega_h_array.hpp>
5 #include <Omega_h_defines.hpp>
6 #include <Omega_h_fail.hpp>
7 #include <Omega_h_scalar.hpp>
41 OMEGA_H_INLINE constexpr
bool code_is_flipped(I8 code) {
return code & 1; }
43 OMEGA_H_INLINE constexpr Int code_rotation(I8 code) {
return (code >> 1) & 3; }
45 OMEGA_H_INLINE constexpr Int code_which_down(I8 code) {
return (code >> 3); }
47 OMEGA_H_INLINE constexpr I8 make_code(
48 bool is_flipped, Int rotation, Int which_down) {
49 return static_cast<I8
>((which_down << 3) | (rotation << 1) | Int(is_flipped));
52 OMEGA_H_INLINE constexpr Int rotate_index(
53 Int nverts_per_ent, Int index, Int rotation) {
54 return (index + rotation) % nverts_per_ent;
59 OMEGA_H_INLINE constexpr Int invert_rotation(Int nverts_per_ent, Int rotation) {
60 return (nverts_per_ent - rotation) % nverts_per_ent;
66 OMEGA_H_INLINE constexpr Int reverse_index(Int n, Int i) {
return n - 1 - i; }
68 OMEGA_H_INLINE constexpr Int flip_vert_index(Int n, Int i) {
69 return (i == 0 ? 0 : (1 + reverse_index(n - 1, i - 1)));
72 OMEGA_H_INLINE constexpr Int flip_edge_index(Int n, Int i) {
73 return reverse_index(n, i);
76 OMEGA_H_INLINE constexpr Int align_vert_index(
77 Int nverts_per_ent, Int index, I8 code) {
78 return code_is_flipped(code)
79 ? flip_vert_index(nverts_per_ent,
80 rotate_index(nverts_per_ent, index, code_rotation(code)))
81 : rotate_index(nverts_per_ent, index, code_rotation(code));
84 OMEGA_H_INLINE constexpr Int align_edge_index(
85 Int nverts_per_ent, Int index, I8 code) {
86 return code_is_flipped(code)
87 ? flip_edge_index(nverts_per_ent,
88 rotate_index(nverts_per_ent, index, code_rotation(code)))
89 : rotate_index(nverts_per_ent, index, code_rotation(code));
92 OMEGA_H_INLINE constexpr Int align_index(
93 Int nverts_per_ent, Int index_dim, Int index, I8 code) {
94 return (index_dim == 0 ? align_vert_index(nverts_per_ent, index, code)
95 : align_edge_index(nverts_per_ent, index, code));
98 OMEGA_H_INLINE constexpr Int rotation_to_first(
99 Int nverts_per_ent, Int new_first) {
100 return invert_rotation(nverts_per_ent, new_first);
103 OMEGA_H_INLINE constexpr I8 invert_alignment(Int nverts_per_ent, I8 code) {
105 return code_is_flipped(code)
108 invert_rotation(nverts_per_ent, code_rotation(code)), 0);
114 template <Int nverts_per_ent>
115 OMEGA_H_INLINE I8 compound_alignments(I8 code1, I8 code2) {
119 Int old_first = align_vert_index(
120 nverts_per_ent, align_vert_index(nverts_per_ent, 0, code1), code2);
123 Int rotation = rotation_to_first(nverts_per_ent, old_first);
124 bool is_flipped = (code_is_flipped(code1) ^ code_is_flipped(code2));
125 return invert_alignment(nverts_per_ent, make_code(is_flipped, rotation, 0));
128 OMEGA_H_INLINE I8 compound_alignments(Int deg, I8 code1, I8 code2) {
129 if (deg == 3)
return compound_alignments<3>(code1, code2);
130 if (deg == 2)
return compound_alignments<2>(code1, code2);
131 OMEGA_H_NORETURN(-1);
134 template <Int nverts_per_ent,
typename In,
typename Out>
135 OMEGA_H_DEVICE
void rotate_adj(
136 Int rotation, In
const& in, LO in_offset, Out& out, LO out_offset) {
137 for (I8 j = 0; j < nverts_per_ent; ++j) {
138 auto out_j = rotate_index(nverts_per_ent, j, rotation);
139 out[out_offset + out_j] = in[in_offset + j];
148 template <
typename InOut>
149 OMEGA_H_DEVICE
static void flip(InOut& adj, LO offset) {
150 swap2(adj[offset + 1], adj[offset + 3]);
156 template <
typename InOut>
157 OMEGA_H_DEVICE
static void flip(InOut& adj, LO offset) {
158 swap2(adj[offset + 1], adj[offset + 2]);
164 template <
typename InOut>
165 OMEGA_H_DEVICE
static void flip(InOut&, LO) {}
168 template <Int deg,
typename InOut>
169 OMEGA_H_DEVICE
void flip_adj(InOut& adj, LO offset) {
173 template <Int nverts_per_ent,
typename In,
typename Out>
174 OMEGA_H_DEVICE
void align_adj(
175 I8 code, In
const& in, LO in_offset, Out& out, LO out_offset) {
176 rotate_adj<nverts_per_ent>(
177 code_rotation(code), in, in_offset, out, out_offset);
178 if (code_is_flipped(code)) flip_adj<nverts_per_ent>(out, out_offset);
181 template <
typename T>
182 Read<T> align_ev2v(Int deg, Read<T> ev2v, Read<I8> codes);
184 #define INST_DECL(T) \
185 extern template Read<T> align_ev2v(Int deg, Read<T> ev2v, Read<I8> codes);
Definition: amr_mpi_test.cpp:6
Definition: Omega_h_align.hpp:144