Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
AMRBlock.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 "shambase/integer.hpp"
21#include "shambackends/vec.hpp"
22#include "shammath/AABB.hpp"
24#include <array>
25
26namespace shammodels::amr {
27
34 template<class Tvec, class TgridVec, u32 _NsideBlockPow>
35 struct AMRBlock {
36 using Tscal = shambase::VecComponent<Tvec>;
37
39
40 static constexpr u32 NsideBlockPow = _NsideBlockPow;
41 static constexpr u32 Nside = 1U << NsideBlockPow;
42 static constexpr u32 side_size = Nside;
43
44 static constexpr u32 block_size = shambase::pow_constexpr<dim>(Nside);
45
52 inline static constexpr u32 get_index(std::array<u32, dim> coord) noexcept {
53 static_assert(dim < 5, "not implemented above dim 4");
54
55 if constexpr (dim == 1) {
56 return coord[0];
57 }
58
59 if constexpr (dim == 2) {
60 return coord[0] + Nside * coord[1];
61 }
62
63 if constexpr (dim == 3) {
64 return coord[0] + Nside * coord[1] + Nside * Nside * coord[2];
65 }
66
67 if constexpr (dim == 4) {
68 return coord[0] + Nside * coord[1] + Nside * Nside * coord[2]
69 + Nside * Nside * Nside * coord[3];
70 }
71
72 return {};
73 }
74
75 inline static constexpr i32 get_index_relative(std::array<i32, dim> coord) noexcept {
76 static_assert(dim < 5, "not implemented above dim 4");
77
78 if constexpr (dim == 1) {
79 return coord[0];
80 }
81
82 if constexpr (dim == 2) {
83 return coord[0] + Nside * coord[1];
84 }
85
86 if constexpr (dim == 3) {
87 return coord[0] + Nside * coord[1] + Nside * Nside * coord[2];
88 }
89
90 if constexpr (dim == 4) {
91 return coord[0] + Nside * coord[1] + Nside * Nside * coord[2]
92 + Nside * Nside * Nside * coord[3];
93 }
94
95 return {};
96 }
97
98 inline static constexpr std::array<u32, dim> get_coord(u32 i) noexcept {
99 static_assert(dim == 3, "only in dim 3 for now");
100
101 if constexpr (dim == 3) {
102 const u32 tmp = i >> NsideBlockPow;
103 return {i % Nside, (tmp) % Nside, (tmp) >> NsideBlockPow};
104 }
105
106 return {};
107 }
108
109 inline static std::pair<Tvec, Tvec> utils_get_cell_coords(
110 std::pair<TgridVec, TgridVec> input, u32 lid) {
111 Tvec block_min = input.first.template convert<Tscal>();
112 Tvec block_max = input.second.template convert<Tscal>();
113 Tvec delta_cell = (block_max - block_min) / side_size;
114
115 std::array<u32, dim> l_coord = get_coord(lid);
116
117 Tvec cell_offset = Tvec{
118 delta_cell.x() * l_coord[0],
119 delta_cell.y() * l_coord[1],
120 delta_cell.z() * l_coord[2]};
121
122 return {block_min + cell_offset, block_min + cell_offset + delta_cell};
123 }
124
125 template<class Func>
126 inline static void for_each_cell_in_block(Tvec delta_cell, Func &&functor) noexcept {
127 static_assert(dim == 3, "implemented only in dim 3");
128 for (u32 ix = 0; ix < side_size; ix++) {
129 for (u32 iy = 0; iy < side_size; iy++) {
130 for (u32 iz = 0; iz < side_size; iz++) {
131 u32 i = get_index({ix, iy, iz});
132 Tvec delta_val = delta_cell * Tvec{ix, iy, iz};
133 functor(i, delta_val);
134 }
135 }
136 }
137 }
138
161 template<class Func>
162 inline static void for_each_cells(
163 sycl::handler &cgh, u32 block_cnt, const char *name, Func &&f) {
164 // we use one thread per subcell because :
165 // double load are avoided because of contiguous L2 cache hit
166 // and CF perf opti for GPU, finer threading lead to better latency hidding
167 shambase::parallel_for(cgh, block_cnt * block_size, name, [=](u64 id_cell) {
168 u32 block_id = id_cell / block_size;
169 f(block_id, id_cell);
170 });
171 }
172
173 template<class Func>
174 inline static void for_each_cells_lid(
175 sycl::handler &cgh, u32 block_cnt, const char *name, Func &&f) {
176 // we use one thread per subcell because :
177 // double load are avoided because of contiguous L2 cache hit
178 // and CF perf opti for GPU, finer threading lead to better latency hidding
179 shambase::parallel_for(cgh, block_cnt * block_size, name, [=](u64 id_cell) {
180 u32 block_id = id_cell / block_size;
181 u32 lid = id_cell % block_size;
182 f(block_id, lid);
183 });
184 }
185
186 template<class Acccellcoord>
187 inline void for_each_neigh_faces(
188 shamrock::tree::ObjectCacheIterator &block_faces_iter,
189 Acccellcoord acc_block_min,
190 Acccellcoord acc_block_max,
191 const u32 id_a,
192 const shammath::AABB<TgridVec> aabb_cell) {
193
194 block_faces_iter.for_each_object(id_a, [&](u32 id_b) {
195 const Tvec block_b_min = acc_block_min[id_a];
196 Tvec block_b_max = acc_block_max[id_a];
197 Tvec delta_cell = (block_b_max - block_b_min) / side_size;
198 });
199 }
200 };
201
202} // namespace shammodels::amr
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
std::int32_t i32
32 bit integer
void throw_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Throw an exception and append the source location to it.
Axis-Aligned bounding box.
Definition AABB.hpp:99
utility class to handle AMR blocks
Definition AMRBlock.hpp:35
static void for_each_cells(sycl::handler &cgh, u32 block_cnt, const char *name, Func &&f)
for each cell routine for amr block. This handle a loop over all the cells in blocks.
Definition AMRBlock.hpp:162
static constexpr u32 get_index(std::array< u32, dim > coord) noexcept
Get the local index within the AMR block.
Definition AMRBlock.hpp:52