File indexing completed on 2026-09-19 08:30:08
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Material/GridSurfaceMaterial.hpp"
0012 #include "Acts/Material/Material.hpp"
0013 #include "Acts/Material/MaterialSlab.hpp"
0014 #include "Acts/Surfaces/CylinderBounds.hpp"
0015 #include "Acts/Surfaces/CylinderSurface.hpp"
0016 #include "Acts/Utilities/AxisDefinitions.hpp"
0017 #include "Acts/Utilities/AxisSpec.hpp"
0018 #include "Acts/Utilities/IAxis.hpp"
0019 #include "Acts/Utilities/MultiAxisSpec.hpp"
0020
0021 #include <numbers>
0022 #include <vector>
0023
0024 using namespace Acts;
0025
0026 namespace ActsTests {
0027
0028 BOOST_AUTO_TEST_SUITE(MaterialSuite)
0029
0030
0031
0032 BOOST_AUTO_TEST_CASE(GridMaterialDirectFromAxes) {
0033 std::vector<std::vector<MaterialSlab>> material2x3;
0034
0035 std::vector<MaterialSlab> materialRow0;
0036 materialRow0.emplace_back(Material::fromMolarDensity(1.0, 2.0, 3.0, 4.0, 5.0),
0037 1.0);
0038 materialRow0.emplace_back(
0039 Material::fromMolarDensity(11.0, 12.0, 13.0, 14.0, 15.0), 2.0);
0040 materialRow0.emplace_back(
0041 Material::fromMolarDensity(21.0, 22.0, 23.0, 24.0, 25.0), 3.0);
0042 std::vector<MaterialSlab> materialRow1;
0043 materialRow1.emplace_back(Material::fromMolarDensity(2.0, 2.0, 3.0, 4.0, 5.0),
0044 1.0);
0045 materialRow1.emplace_back(
0046 Material::fromMolarDensity(12.0, 12.0, 13.0, 14.0, 15.0), 2.0);
0047 materialRow1.emplace_back(
0048 Material::fromMolarDensity(22.0, 22.0, 23.0, 24.0, 25.0), 3.0);
0049
0050 material2x3.push_back(std::move(materialRow0));
0051 material2x3.push_back(std::move(materialRow1));
0052
0053 auto axisX = IAxis::createEquidistant(AxisBoundaryType::Bound, -1.0, 1.0, 2);
0054 auto axisY = IAxis::createEquidistant(AxisBoundaryType::Bound, -1.5, 1.5, 3);
0055
0056 auto ismXY = GridSurfaceMaterial::createDirect(*axisX, *axisY, material2x3);
0057
0058 BOOST_REQUIRE(ismXY != nullptr);
0059
0060
0061 Vector2 l00(-0.5, -1.5);
0062 Vector2 l01(-0.5, 0.);
0063 Vector2 l02(-0.5, 1.5);
0064 Vector2 l10(0.5, -1.5);
0065 Vector2 l11(0.5, 0.);
0066 Vector2 l12(0.5, 1.5);
0067
0068 BOOST_CHECK_EQUAL(ismXY->materialSlab(l00).material().X0(), 1.);
0069 BOOST_CHECK_EQUAL(ismXY->materialSlab(l01).material().X0(), 11.);
0070 BOOST_CHECK_EQUAL(ismXY->materialSlab(l02).material().X0(), 21.);
0071 BOOST_CHECK_EQUAL(ismXY->materialSlab(l10).material().X0(), 2.);
0072 BOOST_CHECK_EQUAL(ismXY->materialSlab(l11).material().X0(), 12.);
0073 BOOST_CHECK_EQUAL(ismXY->materialSlab(l12).material().X0(), 22.);
0074
0075
0076 ismXY->scale(2.);
0077 BOOST_CHECK_EQUAL(ismXY->materialSlab(l00).thickness(), 2.);
0078 BOOST_CHECK_EQUAL(ismXY->materialSlab(l12).thickness(), 6.);
0079 }
0080
0081
0082
0083
0084
0085
0086 BOOST_AUTO_TEST_CASE(GridMaterialDirectFromMultiAxisSpec) {
0087 using enum AxisDirection;
0088
0089 auto cylinder = Surface::makeShared<CylinderSurface>(
0090 Transform3::Identity(), std::make_shared<CylinderBounds>(30., 100.));
0091
0092 MultiAxisSpec2D binning({AxisSpec::DeferredEquidistant(1, AxisRPhi),
0093 AxisSpec::DeferredEquidistant(4, AxisZ)});
0094
0095 std::vector<std::vector<MaterialSlab>> payload = {
0096 {MaterialSlab(Material::fromMolarDensity(1.0, 2.0, 3.0, 4.0, 5.0), 1.0),
0097 MaterialSlab(Material::fromMolarDensity(11.0, 12.0, 13.0, 14.0, 15.0),
0098 2.0),
0099 MaterialSlab(Material::fromMolarDensity(21.0, 22.0, 23.0, 24.0, 25.0),
0100 3.0),
0101 MaterialSlab(Material::fromMolarDensity(31.0, 32.0, 33.0, 34.0, 35.0),
0102 4.0)}};
0103
0104 auto ism = GridSurfaceMaterial::createDirect(binning, *cylinder, payload);
0105 BOOST_REQUIRE(ism != nullptr);
0106
0107
0108
0109 Vector2 lLow(-90., -75.);
0110 Vector2 lMid(1000., -75.);
0111 Vector2 lHigh(90., -75.);
0112 BOOST_CHECK_EQUAL(ism->materialSlab(lLow).material().X0(), 1.);
0113 BOOST_CHECK_EQUAL(ism->materialSlab(lMid).material().X0(), 1.);
0114 BOOST_CHECK_EQUAL(ism->materialSlab(lHigh).material().X0(), 1.);
0115
0116
0117 Vector2 lZ2(0., 25.);
0118 BOOST_CHECK_EQUAL(ism->materialSlab(lZ2).material().X0(), 21.);
0119 }
0120
0121
0122
0123
0124
0125
0126
0127
0128 BOOST_AUTO_TEST_CASE(GridMaterialLocalAxisDirections) {
0129 using enum AxisDirection;
0130
0131 auto axisX = IAxis::createEquidistant(AxisBoundaryType::Bound, -1.0, 1.0, 2);
0132 auto axisY = IAxis::createEquidistant(AxisBoundaryType::Bound, -1.5, 1.5, 3);
0133 std::vector<std::vector<MaterialSlab>> payload2x3 = {
0134 {MaterialSlab::Nothing(), MaterialSlab::Nothing(),
0135 MaterialSlab::Nothing()},
0136 {MaterialSlab::Nothing(), MaterialSlab::Nothing(),
0137 MaterialSlab::Nothing()}};
0138 auto ismUndirected =
0139 GridSurfaceMaterial::createDirect(*axisX, *axisY, payload2x3);
0140 BOOST_CHECK(ismUndirected->localAxisDirections().empty());
0141
0142 auto cylinder = Surface::makeShared<CylinderSurface>(
0143 Transform3::Identity(), std::make_shared<CylinderBounds>(30., 100.));
0144
0145 MultiAxisSpec2D binning({AxisSpec::DeferredEquidistant(1, AxisRPhi),
0146 AxisSpec::DeferredEquidistant(4, AxisZ)});
0147 std::vector<std::vector<MaterialSlab>> payload1x4 = {
0148 {MaterialSlab::Nothing(), MaterialSlab::Nothing(),
0149 MaterialSlab::Nothing(), MaterialSlab::Nothing()}};
0150 auto ismDirected =
0151 GridSurfaceMaterial::createDirect(binning, *cylinder, payload1x4);
0152
0153 std::vector<AxisDirection> localDirs = ismDirected->localAxisDirections();
0154 BOOST_REQUIRE_EQUAL(localDirs.size(), 2u);
0155 BOOST_CHECK_EQUAL(localDirs[0], AxisRPhi);
0156 BOOST_CHECK_EQUAL(localDirs[1], AxisZ);
0157 }
0158
0159
0160
0161
0162 BOOST_AUTO_TEST_CASE(GridIndexedMaterial2D) {
0163 std::vector<MaterialSlab> material;
0164 material.emplace_back(Material::Vacuum(), 1.0);
0165 material.emplace_back(Material::fromMolarDensity(1.0, 2.0, 3.0, 4.0, 5.0),
0166 1.0);
0167 material.emplace_back(
0168 Material::fromMolarDensity(11.0, 12.0, 13.0, 14.0, 15.0), 1.0);
0169 material.emplace_back(
0170 Material::fromMolarDensity(21.0, 22.0, 23.0, 24.0, 25.0), 1.0);
0171
0172
0173 auto axisZ = IAxis::createEquidistant(AxisBoundaryType::Bound, -1.0, 1.0, 2);
0174 auto axisPhi = IAxis::createEquidistant(
0175 AxisBoundaryType::Closed, -std::numbers::pi, std::numbers::pi, 4);
0176
0177 std::vector<std::vector<std::size_t>> indexPayload = {
0178 std::vector<std::size_t>{1u, 1u, 0u, 2u},
0179 std::vector<std::size_t>{0u, 3u, 3u, 0u}};
0180
0181
0182 auto ismFactory = GridSurfaceMaterial::createIndexed(*axisZ, *axisPhi,
0183 material, indexPayload);
0184
0185
0186
0187 MultiAxisSpec2D binning(
0188 {AxisSpec::Equidistant(2, -1.0, 1.0, AxisBoundaryType::Bound),
0189 AxisSpec::Equidistant(4, -std::numbers::pi, std::numbers::pi,
0190 AxisBoundaryType::Closed)});
0191 auto multiAxis = binning.buildMultiAxis();
0192
0193 GridSurfaceMaterial::Indexed storage;
0194 storage.material = material;
0195 storage.indices.resize(multiAxis->getNTotalBins(true), 0u);
0196 for (std::size_t i0 = 0; i0 < indexPayload.size(); ++i0) {
0197 for (std::size_t i1 = 0; i1 < indexPayload[i0].size(); ++i1) {
0198 IMultiAxis2D::LocalBins lbin{i0 + 1, i1 + 1};
0199 storage.indices[multiAxis->getGlobalBinFromLocalBins(lbin)] =
0200 indexPayload[i0][i1];
0201 }
0202 }
0203 GridSurfaceMaterial ism(std::move(binning), std::move(storage));
0204
0205
0206 Vector2 l0(-0.5, -std::numbers::pi * 0.75);
0207 BOOST_CHECK_EQUAL(ism.materialSlab(l0).material().X0(), 1.);
0208 BOOST_CHECK_EQUAL(ismFactory->materialSlab(l0).material().X0(), 1.);
0209
0210 Vector2 l1(0.5, std::numbers::pi / 4.);
0211 BOOST_CHECK_EQUAL(ism.materialSlab(l1).material().X0(), 21.);
0212 BOOST_CHECK_EQUAL(ismFactory->materialSlab(l1).material().X0(), 21.);
0213
0214 Vector2 l2(-0.5, std::numbers::pi / 4.);
0215 BOOST_CHECK(ism.materialSlab(l2).material().isVacuum());
0216 BOOST_CHECK(ismFactory->materialSlab(l2).material().isVacuum());
0217
0218
0219 ism.scale(2.);
0220 BOOST_CHECK_EQUAL(ism.materialSlab(l0).thickness(), 2.);
0221 }
0222
0223
0224
0225
0226 BOOST_AUTO_TEST_CASE(GridGloballyIndexedMaterialNonShared) {
0227 auto material = std::make_shared<std::vector<MaterialSlab>>();
0228
0229 material->emplace_back(Material::Vacuum(), 0.0);
0230 material->emplace_back(Material::fromMolarDensity(1.0, 2.0, 3.0, 4.0, 5.0),
0231 1.0);
0232 material->emplace_back(
0233 Material::fromMolarDensity(11.0, 12.0, 13.0, 14.0, 15.0), 2.0);
0234 material->emplace_back(
0235 Material::fromMolarDensity(21.0, 22.0, 23.0, 24.0, 25.0), 3.0);
0236 material->emplace_back(
0237 Material::fromMolarDensity(31.0, 22.0, 23.0, 24.0, 25.0), 4.0);
0238
0239 auto axis0 = IAxis::createEquidistant(AxisBoundaryType::Bound, 0., 5., 5);
0240 auto axis1 = IAxis::createEquidistant(AxisBoundaryType::Bound, -1., 1., 1);
0241
0242 std::vector<std::vector<std::size_t>> indexPayload = {
0243 {1u}, {0u}, {2u}, {2u}, {3u}};
0244
0245 auto ism = GridSurfaceMaterial::createGloballyIndexed(*axis0, *axis1,
0246 material, indexPayload);
0247
0248
0249 Vector2 l0(0.5, 0.);
0250 Vector2 l1(1.5, 0.);
0251 Vector2 l2(2.5, 0.);
0252 Vector2 l3(3.5, 0.);
0253 Vector2 l4(4.5, 0.);
0254
0255 BOOST_CHECK_EQUAL(ism->materialSlab(l0).material().X0(), 1.);
0256 BOOST_CHECK(ism->materialSlab(l1).material().isVacuum());
0257 BOOST_CHECK_EQUAL(ism->materialSlab(l2).material().X0(), 11.);
0258 BOOST_CHECK_EQUAL(ism->materialSlab(l3).material().X0(), 11.);
0259 BOOST_CHECK_EQUAL(ism->materialSlab(l4).material().X0(), 21.);
0260
0261 auto axis0Single =
0262 IAxis::createEquidistant(AxisBoundaryType::Bound, 0., 5., 1);
0263 std::vector<std::vector<std::size_t>> indexPayload1 = {{4u}};
0264
0265 auto ism1 = GridSurfaceMaterial::createGloballyIndexed(
0266 *axis0Single, *axis1, material, indexPayload1);
0267
0268 Vector2 l0g1(2.5, 0.);
0269 BOOST_CHECK_EQUAL(ism1->materialSlab(l0g1).material().X0(), 31.);
0270
0271
0272 ism1->scale(2.);
0273 BOOST_CHECK_EQUAL(ism1->materialSlab(l0g1).thickness(), 8.);
0274
0275
0276 BOOST_CHECK_EQUAL(ism->materialSlab(l0).thickness(), 1.);
0277 }
0278
0279
0280
0281
0282 BOOST_AUTO_TEST_CASE(GridGloballyIndexedMaterialShared) {
0283 auto material = std::make_shared<std::vector<MaterialSlab>>();
0284
0285 material->emplace_back(Material::Vacuum(), 0.0);
0286 material->emplace_back(Material::fromMolarDensity(1.0, 2.0, 3.0, 4.0, 5.0),
0287 1.0);
0288
0289 auto axis0 = IAxis::createEquidistant(AxisBoundaryType::Bound, 0., 5., 1);
0290 auto axis1 = IAxis::createEquidistant(AxisBoundaryType::Bound, -1., 1., 1);
0291
0292 std::vector<std::vector<std::size_t>> indexPayload = {{1u}};
0293
0294 auto ism0 = GridSurfaceMaterial::createGloballyIndexed(
0295 *axis0, *axis1, material, indexPayload);
0296 auto ism1 = GridSurfaceMaterial::createGloballyIndexed(
0297 *axis0, *axis1, material, indexPayload);
0298
0299 Vector2 l0(2.5, 0.);
0300
0301
0302 BOOST_CHECK_EQUAL(ism0->materialSlab(l0).material().X0(), 1.);
0303 BOOST_CHECK_EQUAL(ism1->materialSlab(l0).material().X0(), 1.);
0304
0305
0306 ism1->scale(2.);
0307 BOOST_CHECK_EQUAL(ism0->materialSlab(l0).thickness(), 2.);
0308 BOOST_CHECK_EQUAL(ism1->materialSlab(l0).thickness(), 2.);
0309 }
0310
0311
0312 BOOST_AUTO_TEST_CASE(GridSurfaceMaterialDirectStorageScale) {
0313 auto axis0 = IAxis::createEquidistant(AxisBoundaryType::Bound, 0., 5., 5);
0314 auto axis1 = IAxis::createEquidistant(AxisBoundaryType::Bound, -1., 1., 1);
0315
0316 std::vector<std::vector<MaterialSlab>> payload = {
0317 {MaterialSlab::Vacuum(0.0)},
0318 {MaterialSlab::Vacuum(1.0)},
0319 {MaterialSlab::Vacuum(2.0)},
0320 {MaterialSlab::Vacuum(3.0)},
0321 {MaterialSlab::Vacuum(4.0)}};
0322
0323 auto gsm = GridSurfaceMaterial::createDirect(*axis0, *axis1, payload);
0324
0325
0326 Vector2 l0(0.5, 0.);
0327 Vector2 l1(1.5, 0.);
0328 Vector2 l2(2.5, 0.);
0329 Vector2 l3(3.5, 0.);
0330 Vector2 l4(4.5, 0.);
0331
0332 BOOST_CHECK_EQUAL(gsm->materialSlab(l0).thickness(), 0.);
0333 BOOST_CHECK_EQUAL(gsm->materialSlab(l1).thickness(), 1.);
0334 BOOST_CHECK_EQUAL(gsm->materialSlab(l2).thickness(), 2.);
0335 BOOST_CHECK_EQUAL(gsm->materialSlab(l3).thickness(), 3.);
0336 BOOST_CHECK_EQUAL(gsm->materialSlab(l4).thickness(), 4.);
0337
0338
0339 gsm->scale(2.);
0340
0341 BOOST_CHECK_EQUAL(gsm->materialSlab(l0).thickness(), 0.);
0342 BOOST_CHECK_EQUAL(gsm->materialSlab(l1).thickness(), 2.);
0343 BOOST_CHECK_EQUAL(gsm->materialSlab(l2).thickness(), 4.);
0344 BOOST_CHECK_EQUAL(gsm->materialSlab(l3).thickness(), 6.);
0345 BOOST_CHECK_EQUAL(gsm->materialSlab(l4).thickness(), 8.);
0346 }
0347
0348
0349
0350
0351 BOOST_AUTO_TEST_CASE(GridSurfaceMaterialConstructionValidation) {
0352 MultiAxisSpec2D binning(
0353 {AxisSpec::Equidistant(2, -1.0, 1.0, AxisBoundaryType::Bound),
0354 AxisSpec::Equidistant(1, -1., 1., AxisBoundaryType::Bound)});
0355 auto multiAxis = binning.buildMultiAxis();
0356 std::size_t nBins = multiAxis->getNTotalBins(true);
0357
0358
0359 GridSurfaceMaterial::Direct direct(nBins);
0360 BOOST_CHECK_NO_THROW(GridSurfaceMaterial(
0361 MultiAxisSpec2D(binning), GridSurfaceMaterial::Direct(direct)));
0362
0363
0364 GridSurfaceMaterial::Direct tooSmall(nBins - 1);
0365 BOOST_CHECK_THROW(
0366 GridSurfaceMaterial(MultiAxisSpec2D(binning), std::move(tooSmall)),
0367 std::invalid_argument);
0368
0369
0370 GridSurfaceMaterial::Indexed indexedTooSmall;
0371 indexedTooSmall.indices.resize(nBins - 1, 0u);
0372 indexedTooSmall.material = {MaterialSlab::Nothing()};
0373 BOOST_CHECK_THROW(
0374 GridSurfaceMaterial(MultiAxisSpec2D(binning), std::move(indexedTooSmall)),
0375 std::invalid_argument);
0376 }
0377
0378 BOOST_AUTO_TEST_SUITE_END()
0379
0380 }