File indexing completed on 2026-05-27 07:24:22
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "detray/definitions/indexing.hpp"
0011 #include "detray/geometry/mask.hpp"
0012 #include "detray/geometry/shapes.hpp"
0013 #include "detray/material/concepts.hpp"
0014 #include "detray/material/material_map.hpp"
0015
0016
0017 #include "detray/test/framework/types.hpp"
0018
0019
0020 #include <gtest/gtest.h>
0021
0022 using namespace detray;
0023 using namespace detray::axis;
0024
0025 using test_algebra = test::algebra;
0026 using scalar = test::scalar;
0027
0028 using material_t =
0029 typename material_grid_factory<test_algebra>::bin_type::entry_type;
0030
0031 namespace {
0032
0033 material_grid_factory<test_algebra> mat_map_factory{};
0034
0035 }
0036
0037
0038 GTEST_TEST(detray_material, annulus_map) {
0039 constexpr scalar minR{7.2f * unit<scalar>::mm};
0040 constexpr scalar maxR{12.0f * unit<scalar>::mm};
0041 constexpr scalar minPhi{0.74195f};
0042 constexpr scalar maxPhi{1.33970f};
0043
0044 mask<annulus2D, test_algebra> ann2{0u, minR, maxR, minPhi,
0045 maxPhi, 0.f, -2.f, 2.f};
0046
0047 auto annulus_map = mat_map_factory.new_grid(ann2, {10u, 20u});
0048
0049 static_assert(concepts::material_map<decltype(annulus_map)>);
0050 static_assert(!concepts::homogeneous_material<decltype(annulus_map)>);
0051 static_assert(concepts::surface_material<decltype(annulus_map)>);
0052 static_assert(!concepts::volume_material<decltype(annulus_map)>);
0053
0054 EXPECT_EQ(annulus_map.dim, 2u);
0055 EXPECT_EQ(annulus_map.nbins(), 200u);
0056
0057 auto r_axis = annulus_map.get_axis<label::e_r>();
0058 EXPECT_EQ(r_axis.nbins(), 10u);
0059 EXPECT_EQ(r_axis.min(), minR);
0060 EXPECT_EQ(r_axis.max(), maxR);
0061
0062 auto phi_axis = annulus_map.get_axis<label::e_phi>();
0063 EXPECT_EQ(phi_axis.nbins(), 20u);
0064 EXPECT_EQ(phi_axis.min(), -minPhi);
0065 EXPECT_EQ(phi_axis.max(), maxPhi);
0066
0067
0068 scalar thickness = 2.f * unit<scalar>::mm;
0069 for (dindex gbin = 0; gbin < annulus_map.nbins(); ++gbin) {
0070 annulus_map.template populate<replace<>>(
0071 gbin, material_t(silicon_tml<scalar>{}, thickness));
0072 thickness += 1.f * unit<scalar>::mm;
0073 }
0074
0075 EXPECT_EQ(annulus_map.at(0, 0),
0076 material_t(silicon_tml<scalar>{}, 2.f * unit<scalar>::mm));
0077 EXPECT_EQ(annulus_map.at(1, 0),
0078 material_t(silicon_tml<scalar>{}, 3.f * unit<scalar>::mm));
0079 EXPECT_EQ(annulus_map.at(22, 0),
0080 material_t(silicon_tml<scalar>{}, 24.f * unit<scalar>::mm));
0081 EXPECT_EQ(annulus_map.at(199, 0),
0082 material_t(silicon_tml<scalar>{}, 201.f * unit<scalar>::mm));
0083 EXPECT_FALSE(annulus_map.at(199, 0) ==
0084 material_t(gold<scalar>{}, 201.f * unit<scalar>::mm));
0085 }
0086
0087
0088 GTEST_TEST(detray_material, cylinder_map) {
0089 constexpr scalar r{3.f * unit<scalar>::mm};
0090 constexpr scalar hz{4.f * unit<scalar>::mm};
0091
0092 mask<cylinder2D, test_algebra> cyl{0u, r, -hz, hz};
0093
0094 auto cylinder_map = mat_map_factory.new_grid(cyl, {10u, 20u});
0095
0096 static_assert(concepts::material_map<decltype(cylinder_map)>);
0097 static_assert(!concepts::homogeneous_material<decltype(cylinder_map)>);
0098 static_assert(concepts::surface_material<decltype(cylinder_map)>);
0099 static_assert(!concepts::volume_material<decltype(cylinder_map)>);
0100
0101 EXPECT_EQ(cylinder_map.dim, 2u);
0102 EXPECT_EQ(cylinder_map.nbins(), 200u);
0103
0104 auto rphi_axis = cylinder_map.get_axis<label::e_rphi>();
0105 EXPECT_EQ(rphi_axis.nbins(), 10u);
0106 EXPECT_EQ(rphi_axis.min(), -constant<scalar>::pi);
0107 EXPECT_EQ(rphi_axis.max(), constant<scalar>::pi);
0108
0109 auto z_axis = cylinder_map.get_axis<label::e_cyl_z>();
0110 EXPECT_EQ(z_axis.nbins(), 20u);
0111 EXPECT_EQ(z_axis.min(), -hz);
0112 EXPECT_EQ(z_axis.max(), hz);
0113
0114 scalar thickness = 2.f * unit<scalar>::mm;
0115 for (dindex gbin = 0; gbin < cylinder_map.nbins(); ++gbin) {
0116 cylinder_map.template populate<replace<>>(
0117 gbin, material_t(vacuum<scalar>{}, thickness));
0118 thickness += 1.f * unit<scalar>::mm;
0119 }
0120
0121 EXPECT_EQ(cylinder_map.at(0, 0),
0122 material_t(vacuum<scalar>{}, 2.f * unit<scalar>::mm));
0123 EXPECT_EQ(cylinder_map.at(1, 0),
0124 material_t(vacuum<scalar>{}, 3.f * unit<scalar>::mm));
0125 EXPECT_EQ(cylinder_map.at(22, 0),
0126 material_t(vacuum<scalar>{}, 24.f * unit<scalar>::mm));
0127 EXPECT_EQ(cylinder_map.at(199, 0),
0128 material_t(vacuum<scalar>{}, 201.f * unit<scalar>::mm));
0129 EXPECT_FALSE(cylinder_map.at(199, 0) ==
0130 material_t(gold<scalar>{}, 201.f * unit<scalar>::mm));
0131 }
0132
0133
0134 GTEST_TEST(detray_material, rectangle_map) {
0135 constexpr scalar hx{1.f * unit<scalar>::mm};
0136 constexpr scalar hy{9.3f * unit<scalar>::mm};
0137
0138 mask<rectangle2D, test_algebra> r2{0u, hx, hy};
0139
0140 auto rectangle_map = mat_map_factory.new_grid(r2, {10u, 20u});
0141
0142 static_assert(concepts::material_map<decltype(rectangle_map)>);
0143 static_assert(!concepts::homogeneous_material<decltype(rectangle_map)>);
0144 static_assert(concepts::surface_material<decltype(rectangle_map)>);
0145 static_assert(!concepts::volume_material<decltype(rectangle_map)>);
0146
0147 EXPECT_EQ(rectangle_map.dim, 2u);
0148 EXPECT_EQ(rectangle_map.nbins(), 200u);
0149
0150 auto x_axis = rectangle_map.get_axis<label::e_x>();
0151 EXPECT_EQ(x_axis.nbins(), 10u);
0152 EXPECT_EQ(x_axis.min(), -hx);
0153 EXPECT_EQ(x_axis.max(), hx);
0154
0155 auto y_axis = rectangle_map.get_axis<label::e_y>();
0156 EXPECT_EQ(y_axis.nbins(), 20u);
0157 EXPECT_EQ(y_axis.min(), -hy);
0158 EXPECT_EQ(y_axis.max(), hy);
0159
0160 scalar thickness = 2.f * unit<scalar>::mm;
0161 for (dindex gbin = 0; gbin < rectangle_map.nbins(); ++gbin) {
0162 rectangle_map.template populate<replace<>>(
0163 gbin, material_t(oxygen_gas<scalar>{}, thickness));
0164 thickness += 1.f * unit<scalar>::mm;
0165 }
0166
0167 EXPECT_EQ(rectangle_map.at(0, 0),
0168 material_t(oxygen_gas<scalar>{}, 2.f * unit<scalar>::mm));
0169 EXPECT_EQ(rectangle_map.at(1, 0),
0170 material_t(oxygen_gas<scalar>{}, 3.f * unit<scalar>::mm));
0171 EXPECT_EQ(rectangle_map.at(22, 0),
0172 material_t(oxygen_gas<scalar>{}, 24.f * unit<scalar>::mm));
0173 EXPECT_EQ(rectangle_map.at(199, 0),
0174 material_t(oxygen_gas<scalar>{}, 201.f * unit<scalar>::mm));
0175 EXPECT_FALSE(rectangle_map.at(199, 0) ==
0176 material_t(gold<scalar>{}, 201.f * unit<scalar>::mm));
0177 }
0178
0179
0180 GTEST_TEST(detray_material, disc_map) {
0181 constexpr scalar inner_r{0.f * unit<scalar>::mm};
0182 constexpr scalar outer_r{3.5f * unit<scalar>::mm};
0183
0184 mask<ring2D, test_algebra> r2{0u, inner_r, outer_r};
0185
0186 auto disc_map = mat_map_factory.new_grid(r2, {10u, 20u});
0187
0188 static_assert(concepts::material_map<decltype(disc_map)>);
0189 static_assert(!concepts::homogeneous_material<decltype(disc_map)>);
0190 static_assert(concepts::surface_material<decltype(disc_map)>);
0191 static_assert(!concepts::volume_material<decltype(disc_map)>);
0192
0193 EXPECT_EQ(disc_map.dim, 2u);
0194 EXPECT_EQ(disc_map.nbins(), 200u);
0195
0196 auto r_axis = disc_map.get_axis<label::e_r>();
0197 EXPECT_EQ(r_axis.nbins(), 10u);
0198 EXPECT_EQ(r_axis.min(), inner_r);
0199 EXPECT_EQ(r_axis.max(), outer_r);
0200
0201 auto phi_axis = disc_map.get_axis<label::e_phi>();
0202 EXPECT_EQ(phi_axis.nbins(), 20u);
0203 EXPECT_EQ(phi_axis.min(), -constant<scalar>::pi);
0204 EXPECT_EQ(phi_axis.max(), constant<scalar>::pi);
0205
0206 scalar thickness = 2.f * unit<scalar>::mm;
0207 for (dindex gbin = 0; gbin < disc_map.nbins(); ++gbin) {
0208 disc_map.template populate<replace<>>(
0209 gbin, material_t(aluminium<scalar>{}, thickness));
0210 thickness += 1.f * unit<scalar>::mm;
0211 }
0212
0213 EXPECT_EQ(disc_map.at(0, 0),
0214 material_t(aluminium<scalar>{}, 2.f * unit<scalar>::mm));
0215 EXPECT_EQ(disc_map.at(1, 0),
0216 material_t(aluminium<scalar>{}, 3.f * unit<scalar>::mm));
0217 EXPECT_EQ(disc_map.at(22, 0),
0218 material_t(aluminium<scalar>{}, 24.f * unit<scalar>::mm));
0219 EXPECT_EQ(disc_map.at(199, 0),
0220 material_t(aluminium<scalar>{}, 201.f * unit<scalar>::mm));
0221 EXPECT_FALSE(disc_map.at(199, 0) ==
0222 material_t(gold<scalar>{}, 201.f * unit<scalar>::mm));
0223 }
0224
0225
0226 GTEST_TEST(detray_material, trapezoid_map) {
0227 constexpr scalar hx_miny{1.f * unit<scalar>::mm};
0228 constexpr scalar hx_maxy{3.f * unit<scalar>::mm};
0229 constexpr scalar hy{2.f * unit<scalar>::mm};
0230 constexpr scalar divisor{1.f / (2.f * hy)};
0231
0232 mask<trapezoid2D, test_algebra> t2{0u, hx_miny, hx_maxy, hy, divisor};
0233
0234 auto trapezoid_map = mat_map_factory.new_grid(t2, {10u, 20u});
0235
0236 static_assert(concepts::material_map<decltype(trapezoid_map)>);
0237 static_assert(!concepts::homogeneous_material<decltype(trapezoid_map)>);
0238 static_assert(concepts::surface_material<decltype(trapezoid_map)>);
0239 static_assert(!concepts::volume_material<decltype(trapezoid_map)>);
0240
0241 EXPECT_EQ(trapezoid_map.dim, 2u);
0242 EXPECT_EQ(trapezoid_map.nbins(), 200u);
0243
0244 auto x_axis = trapezoid_map.get_axis<label::e_x>();
0245 EXPECT_EQ(x_axis.nbins(), 10u);
0246 EXPECT_EQ(x_axis.min(), -hx_maxy);
0247 EXPECT_EQ(x_axis.max(), hx_maxy);
0248
0249 auto y_axis = trapezoid_map.get_axis<label::e_y>();
0250 EXPECT_EQ(y_axis.nbins(), 20u);
0251 EXPECT_EQ(y_axis.min(), -hy);
0252 EXPECT_EQ(y_axis.max(), hy);
0253
0254 scalar thickness = 2.f * unit<scalar>::mm;
0255 for (dindex gbin = 0; gbin < trapezoid_map.nbins(); ++gbin) {
0256 trapezoid_map.template populate<replace<>>(
0257 gbin, material_t(gold<scalar>{}, thickness));
0258 thickness += 1.f * unit<scalar>::mm;
0259 }
0260
0261 EXPECT_EQ(trapezoid_map.at(0, 0),
0262 material_t(gold<scalar>{}, 2.f * unit<scalar>::mm));
0263 EXPECT_EQ(trapezoid_map.at(1, 0),
0264 material_t(gold<scalar>{}, 3.f * unit<scalar>::mm));
0265 EXPECT_EQ(trapezoid_map.at(22, 0),
0266 material_t(gold<scalar>{}, 24.f * unit<scalar>::mm));
0267 EXPECT_EQ(trapezoid_map.at(199, 0),
0268 material_t(gold<scalar>{}, 201.f * unit<scalar>::mm));
0269 EXPECT_FALSE(trapezoid_map.at(199, 0) ==
0270 material_t(aluminium<scalar>{}, 201.f * unit<scalar>::mm));
0271 }
0272
0273
0274 GTEST_TEST(detray_material, material_grid_comparison) {
0275
0276
0277
0278
0279
0280
0281 auto createGrid = [](const scalar hx, const scalar hy, unsigned int bx,
0282 unsigned int by, bool distort_entries) {
0283 mask<rectangle2D, test_algebra> r2{0u, hx, hy};
0284 auto material_grid = mat_map_factory.new_grid(r2, {bx, by});
0285
0286
0287 scalar thickness = 2.f * unit<scalar>::mm;
0288 for (dindex gbin = 0; gbin < material_grid.nbins(); ++gbin) {
0289 material_grid.template populate<replace<>>(
0290 gbin, material_t(oxygen_gas<scalar>{}, thickness));
0291 thickness += 1.f * unit<scalar>::mm;
0292 if (distort_entries) {
0293 thickness += 1.f * unit<scalar>::mm;
0294 }
0295 }
0296
0297 return material_grid;
0298 };
0299
0300
0301 auto grid_ref = createGrid(10.f, 20.f, 10u, 20u, false);
0302 auto grid_eq = createGrid(10.f, 20.f, 10u, 20u, false);
0303 EXPECT_EQ(grid_ref, grid_eq);
0304
0305
0306 auto grid_neq_size = createGrid(11.f, 21.f, 10u, 20u, false);
0307 EXPECT_NE(grid_ref, grid_neq_size);
0308
0309
0310 auto grid_neq_bins = createGrid(10.f, 20.f, 11u, 21u, false);
0311 EXPECT_NE(grid_ref, grid_neq_bins);
0312
0313
0314 auto grid_neq_entries = createGrid(10.f, 20.f, 10u, 20u, true);
0315 EXPECT_NE(grid_ref, grid_neq_entries);
0316 }