Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:42

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #include <boost/test/unit_test.hpp>
0010 
0011 #include "Acts/Material/Material.hpp"
0012 #include "Acts/Material/MaterialSlab.hpp"
0013 #include "Acts/Material/detail/AverageMaterials.hpp"
0014 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0015 #include "Acts/Tests/CommonHelpers/PredefinedMaterials.hpp"
0016 
0017 #include <cmath>
0018 #include <limits>
0019 
0020 namespace {
0021 
0022 using Acts::detail::combineSlabs;
0023 
0024 constexpr auto eps = std::numeric_limits<float>::epsilon();
0025 
0026 // vacuum w/ different thickness
0027 const Acts::MaterialSlab zeroVacuum = Acts::MaterialSlab(0.0f);
0028 const Acts::MaterialSlab unitVacuum = Acts::MaterialSlab(1.0f);
0029 // same material corresponding to 0%, 1% and 100% radiation/interaction length
0030 const Acts::MaterialSlab zero(Acts::Test::makeSilicon(), 0.0f);
0031 const Acts::MaterialSlab percent = Acts::Test::makePercentSlab();
0032 const Acts::MaterialSlab unit = Acts::Test::makeUnitSlab();
0033 
0034 }  // namespace
0035 
0036 BOOST_AUTO_TEST_SUITE(AverageMaterials)
0037 
0038 // average two identical slabs
0039 
0040 BOOST_AUTO_TEST_CASE(CombineSlabsVacuum) {
0041   // vacuum with zero thickness
0042   {
0043     auto slab = combineSlabs(zeroVacuum, zeroVacuum);
0044     BOOST_CHECK(!slab.isValid());
0045     BOOST_CHECK(!slab.material().isValid());
0046     BOOST_CHECK_EQUAL(slab.thickness(), 0.0f);
0047     BOOST_CHECK_EQUAL(slab.thicknessInX0(), 0.0f);
0048     BOOST_CHECK_EQUAL(slab.thicknessInL0(), 0.0f);
0049   }
0050   // vacuum with unit thickness
0051   {
0052     auto slab = combineSlabs(unitVacuum, unitVacuum);
0053     BOOST_CHECK(!slab.isValid());
0054     BOOST_CHECK(!slab.material().isValid());
0055     BOOST_CHECK_EQUAL(slab.thickness(), 2.0f);
0056     BOOST_CHECK_EQUAL(slab.thicknessInX0(), 0.0f);
0057     BOOST_CHECK_EQUAL(slab.thicknessInL0(), 0.0f);
0058   }
0059 }
0060 
0061 BOOST_AUTO_TEST_CASE(CombineSlabsPercent) {
0062   auto slab = combineSlabs(percent, percent);
0063   // combining two identical slabs must give the same average material
0064   BOOST_CHECK(slab.isValid());
0065   BOOST_CHECK(slab.material().isValid());
0066   BOOST_CHECK_EQUAL(slab.material(), percent.material());
0067   // thickness-like properties must double
0068   BOOST_CHECK_EQUAL(slab.thickness(), 2 * percent.thickness());
0069   BOOST_CHECK_EQUAL(slab.thicknessInX0(), 2 * percent.thicknessInX0());
0070   BOOST_CHECK_EQUAL(slab.thicknessInL0(), 2 * percent.thicknessInL0());
0071 }
0072 
0073 BOOST_AUTO_TEST_CASE(CombineSlabsUnit) {
0074   auto slab = combineSlabs(unit, unit);
0075   // combining two identical slabs must give the same average material
0076   BOOST_CHECK(slab.isValid());
0077   BOOST_CHECK(slab.material().isValid());
0078   BOOST_CHECK_EQUAL(slab.material(), unit.material());
0079   // thickness-like properties must double
0080   BOOST_CHECK_EQUAL(slab.thickness(), 2 * unit.thickness());
0081   BOOST_CHECK_EQUAL(slab.thicknessInX0(), 2 * unit.thicknessInX0());
0082   BOOST_CHECK_EQUAL(slab.thicknessInL0(), 2 * unit.thicknessInL0());
0083 }
0084 
0085 // average a non-vacuum slab and a zero-thickness vacuum slab
0086 
0087 BOOST_AUTO_TEST_CASE(CombineSlabsPercentZeroVacuum) {
0088   {
0089     auto slab = combineSlabs(percent, zeroVacuum);
0090     BOOST_CHECK(slab.isValid());
0091     BOOST_CHECK(slab.material().isValid());
0092     BOOST_CHECK_EQUAL(slab.material(), percent.material());
0093     BOOST_CHECK_EQUAL(slab.thickness(), percent.thickness());
0094     BOOST_CHECK_EQUAL(slab.thicknessInX0(), percent.thicknessInX0());
0095     BOOST_CHECK_EQUAL(slab.thicknessInL0(), percent.thicknessInL0());
0096   }
0097   // reverse input order
0098   {
0099     auto slab = combineSlabs(zeroVacuum, percent);
0100     BOOST_CHECK(slab.isValid());
0101     BOOST_CHECK(slab.material().isValid());
0102     BOOST_CHECK_EQUAL(slab.material(), percent.material());
0103     BOOST_CHECK_EQUAL(slab.thickness(), percent.thickness());
0104     BOOST_CHECK_EQUAL(slab.thicknessInX0(), percent.thicknessInX0());
0105     BOOST_CHECK_EQUAL(slab.thicknessInL0(), percent.thicknessInL0());
0106   }
0107 }
0108 
0109 BOOST_AUTO_TEST_CASE(CombineSlabsUnitZeroVacuum) {
0110   {
0111     auto slab = combineSlabs(unit, zeroVacuum);
0112     BOOST_CHECK(slab.isValid());
0113     BOOST_CHECK(slab.material().isValid());
0114     BOOST_CHECK_EQUAL(slab.material(), unit.material());
0115     BOOST_CHECK_EQUAL(slab.thickness(), unit.thickness());
0116     BOOST_CHECK_EQUAL(slab.thicknessInX0(), unit.thicknessInX0());
0117     BOOST_CHECK_EQUAL(slab.thicknessInL0(), unit.thicknessInL0());
0118   }
0119   // reverse input order
0120   {
0121     auto slab = combineSlabs(zeroVacuum, unit);
0122     BOOST_CHECK(slab.isValid());
0123     BOOST_CHECK(slab.material().isValid());
0124     BOOST_CHECK_EQUAL(slab.material(), unit.material());
0125     BOOST_CHECK_EQUAL(slab.thickness(), unit.thickness());
0126     BOOST_CHECK_EQUAL(slab.thicknessInX0(), unit.thicknessInX0());
0127     BOOST_CHECK_EQUAL(slab.thicknessInL0(), unit.thicknessInL0());
0128   }
0129 }
0130 
0131 // average two non-vacuum slabs with the same material but different thickness
0132 
0133 BOOST_AUTO_TEST_CASE(CombineSlabsPercentUnit) {
0134   // the two slabs have the same material -> average should be identical
0135   {
0136     auto slab = combineSlabs(percent, unit);
0137     BOOST_CHECK(slab.isValid());
0138     BOOST_CHECK(slab.material().isValid());
0139     BOOST_CHECK_EQUAL(slab.material(), percent.material());
0140     BOOST_CHECK_EQUAL(slab.thickness(), percent.thickness() + unit.thickness());
0141     BOOST_CHECK_EQUAL(slab.thicknessInX0(),
0142                       percent.thicknessInX0() + unit.thicknessInX0());
0143     BOOST_CHECK_EQUAL(slab.thicknessInL0(),
0144                       percent.thicknessInL0() + unit.thicknessInL0());
0145   }
0146   // reverse input order
0147   {
0148     auto slab = combineSlabs(unit, percent);
0149     BOOST_CHECK(slab.isValid());
0150     BOOST_CHECK(slab.material().isValid());
0151     BOOST_CHECK_EQUAL(slab.material(), unit.material());
0152     BOOST_CHECK_EQUAL(slab.thickness(), unit.thickness() + percent.thickness());
0153     BOOST_CHECK_EQUAL(slab.thicknessInX0(),
0154                       percent.thicknessInX0() + unit.thicknessInX0());
0155     BOOST_CHECK_EQUAL(slab.thicknessInL0(),
0156                       percent.thicknessInL0() + unit.thicknessInL0());
0157   }
0158 }
0159 
0160 // average two non-vacuum slabs where one has zero thickness
0161 
0162 BOOST_AUTO_TEST_CASE(CombineSlabsUnitZero) {
0163   // the two slabs have the same material -> average should be identical
0164   {
0165     auto slab = combineSlabs(unit, zero);
0166     BOOST_CHECK(slab.isValid());
0167     BOOST_CHECK(slab.material().isValid());
0168     BOOST_CHECK_EQUAL(slab.material(), unit.material());
0169     BOOST_CHECK_EQUAL(slab.thickness(), unit.thickness());
0170     BOOST_CHECK_EQUAL(slab.thicknessInX0(), unit.thicknessInX0());
0171     BOOST_CHECK_EQUAL(slab.thicknessInL0(), unit.thicknessInL0());
0172   }
0173   // reverse input order
0174   {
0175     auto slab = combineSlabs(zero, unit);
0176     BOOST_CHECK(slab.isValid());
0177     BOOST_CHECK(slab.material().isValid());
0178     BOOST_CHECK_EQUAL(slab.material(), unit.material());
0179     BOOST_CHECK_EQUAL(slab.thickness(), unit.thickness());
0180     BOOST_CHECK_EQUAL(slab.thicknessInX0(), unit.thicknessInX0());
0181     BOOST_CHECK_EQUAL(slab.thicknessInL0(), unit.thicknessInL0());
0182   }
0183 }
0184 
0185 // average a non-vacuum and a vacuum slab w/ equal thickness
0186 
0187 BOOST_AUTO_TEST_CASE(CombineSlabsEqualThicknessVacuum) {
0188   const auto mat = Acts::Test::makeSilicon();
0189   const auto slabMat = Acts::MaterialSlab(mat, 1.0f);
0190   const auto slabVac = Acts::MaterialSlab(Acts::Material(), 1.0f);
0191   {
0192     auto slab = combineSlabs(slabMat, slabVac);
0193     BOOST_CHECK(slab.isValid());
0194     BOOST_CHECK(slab.material().isValid());
0195     BOOST_CHECK_EQUAL(slab.thickness(), 2.0f);
0196     BOOST_CHECK_EQUAL(slab.thicknessInX0(), slabMat.thicknessInX0());
0197     BOOST_CHECK_EQUAL(slab.thicknessInL0(), slabMat.thicknessInL0());
0198     // atomic mass and nuclear charge are per atom, adding any amount vacuum
0199     // does not change the average atom properties only their density
0200     BOOST_CHECK_EQUAL(slab.material().Ar(), mat.Ar());
0201     BOOST_CHECK_EQUAL(slab.material().Z(), 0.5 * mat.Z());
0202     // we have the same type of interactions just spread over twice the length
0203     CHECK_CLOSE_REL(slab.material().X0(), 2.0f * mat.X0(), eps);
0204     CHECK_CLOSE_REL(slab.material().L0(), 2.0f * mat.L0(), eps);
0205     // we have the same atoms just spread over more volume
0206     BOOST_CHECK_EQUAL(slab.material().molarDensity(),
0207                       0.5f * mat.molarDensity());
0208   }
0209   // reverse input order
0210   {
0211     auto slab = combineSlabs(slabVac, slabMat);
0212     BOOST_CHECK(slab.isValid());
0213     BOOST_CHECK(slab.material().isValid());
0214     BOOST_CHECK_EQUAL(slab.thickness(), 2.0f);
0215     BOOST_CHECK_EQUAL(slab.thicknessInX0(), slabMat.thicknessInX0());
0216     BOOST_CHECK_EQUAL(slab.thicknessInL0(), slabMat.thicknessInL0());
0217     // atomic mass and nuclear charge are per atom, adding any amount vacuum
0218     // does not change the average atom properties only their density
0219     BOOST_CHECK_EQUAL(slab.material().Ar(), mat.Ar());
0220     BOOST_CHECK_EQUAL(slab.material().Z(), 0.5 * mat.Z());
0221     // we have the same type of interactions just spread over twice the length
0222     CHECK_CLOSE_REL(slab.material().X0(), 2.0f * mat.X0(), eps);
0223     CHECK_CLOSE_REL(slab.material().L0(), 2.0f * mat.L0(), eps);
0224     // we have the same atoms just spread over more volume
0225     BOOST_CHECK_EQUAL(slab.material().molarDensity(),
0226                       0.5f * mat.molarDensity());
0227   }
0228 }
0229 
0230 // average two non-vacuum slabs w/ different material and different thickness
0231 
0232 BOOST_AUTO_TEST_CASE(CombineSlabs) {
0233   const auto mat0 = Acts::Material::fromMolarDensity(1, 1, 8, 12, 2);
0234   const auto mat1 = Acts::Material::fromMolarDensity(2, 2, 2, 6, 5);
0235   const auto slabMat0 = Acts::MaterialSlab(mat0, 0.5f);
0236   const auto slabMat1 = Acts::MaterialSlab(mat1, 1.0f);
0237   // verify derived quantities for the input slabs. these tests are not really
0238   // needed, but to show the input values for the tests below.
0239   BOOST_CHECK(slabMat0.isValid());
0240   BOOST_CHECK(slabMat0.material().isValid());
0241   BOOST_CHECK_EQUAL(slabMat0.thickness(), 0.5f);
0242   BOOST_CHECK_EQUAL(slabMat0.thicknessInX0(), 0.5f);
0243   BOOST_CHECK_EQUAL(slabMat0.thicknessInL0(), 0.5f);
0244   BOOST_CHECK(slabMat1.isValid());
0245   BOOST_CHECK(slabMat1.material().isValid());
0246   BOOST_CHECK_EQUAL(slabMat1.thickness(), 1.0f);
0247   BOOST_CHECK_EQUAL(slabMat1.thicknessInX0(), 0.5f);
0248   BOOST_CHECK_EQUAL(slabMat1.thicknessInL0(), 0.5f);
0249   // check combined slabs
0250   {
0251     auto slab = combineSlabs(slabMat0, slabMat1);
0252     BOOST_CHECK(slab.isValid());
0253     BOOST_CHECK(slab.material().isValid());
0254     BOOST_CHECK_EQUAL(slab.thickness(), 1.5f);
0255     BOOST_CHECK_EQUAL(slab.thicknessInX0(), 1.0f);
0256     BOOST_CHECK_EQUAL(slab.thicknessInL0(), 1.0f);
0257     BOOST_CHECK_EQUAL(slab.material().X0(), 1.5f);
0258     BOOST_CHECK_EQUAL(slab.material().L0(), 1.5f);
0259     BOOST_CHECK_EQUAL(slab.material().Ar(), 3.0f);
0260     BOOST_CHECK_EQUAL(slab.material().Z(),
0261                       static_cast<float>(
0262                           exp((0.5 / 1.5) * log(12.0) + (1.0 / 1.5) * log(6))));
0263     BOOST_CHECK_EQUAL(slab.material().molarDensity(), 4.0f);
0264   }
0265   // reverse input order
0266   {
0267     auto slab = combineSlabs(slabMat0, slabMat1);
0268     BOOST_CHECK(slab.isValid());
0269     BOOST_CHECK(slab.material().isValid());
0270     BOOST_CHECK_EQUAL(slab.thickness(), 1.5f);
0271     BOOST_CHECK_EQUAL(slab.thicknessInX0(), 1.0f);
0272     BOOST_CHECK_EQUAL(slab.thicknessInL0(), 1.0f);
0273     BOOST_CHECK_EQUAL(slab.material().X0(), 1.5f);
0274     BOOST_CHECK_EQUAL(slab.material().L0(), 1.5f);
0275     BOOST_CHECK_EQUAL(slab.material().Ar(), 3.0f);
0276     BOOST_CHECK_EQUAL(slab.material().Z(),
0277                       static_cast<float>(
0278                           exp((0.5 / 1.5) * log(12.0) + (1.0 / 1.5) * log(6))));
0279     BOOST_CHECK_EQUAL(slab.material().molarDensity(), 4.0f);
0280   }
0281 }
0282 
0283 BOOST_AUTO_TEST_SUITE_END()