Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
PatchCoord.hpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
10#pragma once
11
18#include "shambackends/sycl.hpp"
20
21namespace shamrock::patch {
22
23 template<u32 dim = 3U>
24 class PatchCoord {
25 public:
26 static constexpr u32 splts_count = 1U << dim;
27
28 std::array<u64, dim> coord_min;
29 std::array<u64, dim> coord_max;
30
31 PatchCoord() = default;
32
33 PatchCoord(std::array<u64, dim> coord_min, std::array<u64, dim> coord_max)
34 : coord_min(coord_min), coord_max(coord_max) {}
35
36 [[nodiscard]] inline static auto get_split_coord(
37 std::array<u64, dim> coord_min, std::array<u64, dim> coord_max)
38 -> std::array<u64, dim> {
39 return {
40 (((coord_max[0] - coord_min[0]) + 1) / 2) - 1 + coord_min[0],
41 (((coord_max[1] - coord_min[1]) + 1) / 2) - 1 + coord_min[1],
42 (((coord_max[2] - coord_min[2]) + 1) / 2) - 1 + coord_min[2]};
43 }
44
45 inline static auto get_split(std::array<u64, dim> coord_min, std::array<u64, dim> coord_max)
46 -> std::array<PatchCoord, splts_count> {
47
48 std::array<PatchCoord, splts_count> pret;
49
50 auto splts = get_split_coord(coord_min, coord_max);
51
52 u64 split_x = splts[0];
53 u64 split_y = splts[1];
54 u64 split_z = splts[2];
55
56 pret[0].coord_min[0] = coord_min[0];
57 pret[0].coord_min[1] = coord_min[1];
58 pret[0].coord_min[2] = coord_min[2];
59 pret[0].coord_max[0] = split_x;
60 pret[0].coord_max[1] = split_y;
61 pret[0].coord_max[2] = split_z;
62
63 pret[1].coord_min[0] = coord_min[0];
64 pret[1].coord_min[1] = coord_min[1];
65 pret[1].coord_min[2] = split_z + 1;
66 pret[1].coord_max[0] = split_x;
67 pret[1].coord_max[1] = split_y;
68 pret[1].coord_max[2] = coord_max[2];
69
70 pret[2].coord_min[0] = coord_min[0];
71 pret[2].coord_min[1] = split_y + 1;
72 pret[2].coord_min[2] = coord_min[2];
73 pret[2].coord_max[0] = split_x;
74 pret[2].coord_max[1] = coord_max[1];
75 pret[2].coord_max[2] = split_z;
76
77 pret[3].coord_min[0] = coord_min[0];
78 pret[3].coord_min[1] = split_y + 1;
79 pret[3].coord_min[2] = split_z + 1;
80 pret[3].coord_max[0] = split_x;
81 pret[3].coord_max[1] = coord_max[1];
82 pret[3].coord_max[2] = coord_max[2];
83
84 pret[4].coord_min[0] = split_x + 1;
85 pret[4].coord_min[1] = coord_min[1];
86 pret[4].coord_min[2] = coord_min[2];
87 pret[4].coord_max[0] = coord_max[0];
88 pret[4].coord_max[1] = split_y;
89 pret[4].coord_max[2] = split_z;
90
91 pret[5].coord_min[0] = split_x + 1;
92 pret[5].coord_min[1] = coord_min[1];
93 pret[5].coord_min[2] = split_z + 1;
94 pret[5].coord_max[0] = coord_max[0];
95 pret[5].coord_max[1] = split_y;
96 pret[5].coord_max[2] = coord_max[2];
97
98 pret[6].coord_min[0] = split_x + 1;
99 pret[6].coord_min[1] = split_y + 1;
100 pret[6].coord_min[2] = coord_min[2];
101 pret[6].coord_max[0] = coord_max[0];
102 pret[6].coord_max[1] = coord_max[1];
103 pret[6].coord_max[2] = split_z;
104
105 pret[7].coord_min[0] = split_x + 1;
106 pret[7].coord_min[1] = split_y + 1;
107 pret[7].coord_min[2] = split_z + 1;
108 pret[7].coord_max[0] = coord_max[0];
109 pret[7].coord_max[1] = coord_max[1];
110 pret[7].coord_max[2] = coord_max[2];
111
112 return pret;
113 }
114
115 inline auto split() -> std::array<PatchCoord, splts_count> {
116 return get_split(coord_min, coord_max);
117 }
118
119 inline static PatchCoord merge(PatchCoord c1, PatchCoord c2) {
120 return PatchCoord(
121 {sycl::min(c1.coord_min[0], c2.coord_min[0]),
122 sycl::min(c1.coord_min[1], c2.coord_min[1]),
123 sycl::min(c1.coord_min[2], c2.coord_min[2])},
124 {sycl::max(c1.coord_max[0], c2.coord_max[0]),
125 sycl::max(c1.coord_max[1], c2.coord_max[1]),
126 sycl::max(c1.coord_max[2], c2.coord_max[2])});
127 }
128
129 inline static PatchCoord merge(std::array<PatchCoord, splts_count> others) {
130 return merge(
131 merge(merge(others[0], others[1]), merge(others[2], others[3])),
132 merge(merge(others[4], others[5]), merge(others[6], others[7])));
133 }
134
135 [[nodiscard]] shammath::CoordRange<u64_3> get_patch_range() const {
136 return {
137 u64_3{coord_min[0], coord_min[1], coord_min[2]},
138 u64_3{coord_max[0], coord_max[1], coord_max[2]} + 1};
139 }
140
141 template<class T>
142 inline static std::tuple<sycl::vec<T, 3>, sycl::vec<T, 3>> convert_coord(
143 std::array<u64, dim> coord_min,
144 std::array<u64, dim> coord_max,
145 std::array<u64, dim> pcoord_offset,
146 sycl::vec<T, 3> divfact,
147 sycl::vec<T, 3> offset) {
148
149 using vec = sycl::vec<T, 3>;
150
151 vec min_bound = vec{coord_min[0] - pcoord_offset[0],
152 coord_min[1] - pcoord_offset[1],
153 coord_min[2] - pcoord_offset[2]}
154 / divfact
155 + offset;
156 vec max_bound = (vec{coord_max[0] - pcoord_offset[0],
157 coord_max[1] - pcoord_offset[1],
158 coord_max[2] - pcoord_offset[2]}
159 + 1)
160 / divfact
161 + offset;
162
163 return {min_bound, max_bound};
164 }
165 };
166
167 template<u32 dim = 3U>
168 inline bool operator==(const PatchCoord<dim> &lhs, const PatchCoord<dim> &rhs) {
169 return (lhs.coord_min == rhs.coord_min) && (lhs.coord_max == rhs.coord_max);
170 }
171} // namespace shamrock::patch
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer