File indexing completed on 2025-10-18 08:23:01
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Units.hpp"
0012 #include "Acts/Material/MaterialSlab.hpp"
0013 #include "ActsFatras/EventData/Barcode.hpp"
0014 #include "ActsFatras/EventData/Particle.hpp"
0015 #include "ActsFatras/Kernel/InteractionList.hpp"
0016 #include "ActsTests/CommonHelpers/PredefinedMaterials.hpp"
0017
0018 #include <cstdint>
0019 #include <limits>
0020 #include <random>
0021 #include <utility>
0022 #include <vector>
0023
0024 using namespace Acts;
0025 using namespace Acts::UnitLiterals;
0026 using namespace ActsFatras;
0027 using namespace ActsFatras::detail;
0028
0029 namespace {
0030
0031
0032 struct SterileContinuousProcess {
0033 template <typename generator_t>
0034 bool operator()(generator_t & , const MaterialSlab & ,
0035 Particle & ,
0036 std::vector<Particle> & ) const {
0037 return false;
0038 }
0039 };
0040
0041 static_assert(ContinuousProcessConcept<SterileContinuousProcess>,
0042 "Is not a continuous process");
0043 static_assert(!PointLikeProcessConcept<SterileContinuousProcess>,
0044 "Is a point-like process");
0045
0046
0047 struct FatalContinuousProcess {
0048 template <typename generator_t>
0049 bool operator()(generator_t & , const MaterialSlab & ,
0050 Particle & ,
0051 std::vector<Particle> & ) const {
0052 return true;
0053 }
0054 };
0055 static_assert(ContinuousProcessConcept<FatalContinuousProcess>,
0056 "Is not a continuous process");
0057 static_assert(!PointLikeProcessConcept<FatalContinuousProcess>,
0058 "Is a point-like process");
0059
0060
0061
0062
0063 struct X0PointLikeProcess {
0064 template <typename generator_t>
0065 std::pair<double, double> generatePathLimits(
0066 generator_t & , const Particle & ) const {
0067 return {0.5, std::numeric_limits<double>::infinity()};
0068 }
0069
0070 template <typename generator_t>
0071 bool run(generator_t & , Particle &particle,
0072 std::vector<Particle> &generated) const {
0073 auto pid0 = particle.particleId().makeDescendant(0);
0074 generated.emplace_back(particle.withParticleId(pid0));
0075 return false;
0076 }
0077 };
0078
0079 static_assert(!ContinuousProcessConcept<X0PointLikeProcess>,
0080 "Is a continuous process");
0081 static_assert(PointLikeProcessConcept<X0PointLikeProcess>,
0082 "Is not a point-like process");
0083
0084
0085
0086
0087 struct L0PointLikeProcess {
0088 template <typename generator_t>
0089 std::pair<double, double> generatePathLimits(
0090 generator_t & , const Particle & ) const {
0091 return {std::numeric_limits<double>::infinity(), 1.5};
0092 }
0093
0094 template <typename generator_t>
0095 bool run(generator_t & , Particle &particle,
0096 std::vector<Particle> &generated) const {
0097 auto pid0 = particle.particleId().makeDescendant(0);
0098 auto pid1 = particle.particleId().makeDescendant(1);
0099 generated.emplace_back(particle.withParticleId(pid0));
0100 generated.emplace_back(particle.withParticleId(pid1));
0101 return true;
0102 }
0103 };
0104
0105 static_assert(!ContinuousProcessConcept<L0PointLikeProcess>,
0106 "Is a continuous process");
0107 static_assert(PointLikeProcessConcept<L0PointLikeProcess>,
0108 "Is not a point-like process");
0109
0110 struct Fixture {
0111 std::ranlux48 rng{23};
0112 MaterialSlab slab = MaterialSlab(ActsTests::makeBeryllium(), 1_mm);
0113 Particle incoming;
0114 std::vector<Particle> outgoing;
0115 };
0116
0117 }
0118
0119 namespace ActsTests {
0120
0121 BOOST_AUTO_TEST_SUITE(KernelSuite)
0122
0123 BOOST_AUTO_TEST_CASE(Empty) {
0124 Fixture f;
0125 InteractionList<> l;
0126
0127
0128 BOOST_CHECK(!l.runContinuous(f.rng, f.slab, f.incoming, f.outgoing));
0129
0130
0131 auto sel = l.armPointLike(f.rng, f.incoming);
0132 BOOST_CHECK_EQUAL(sel.x0Limit, std::numeric_limits<double>::infinity());
0133 BOOST_CHECK_EQUAL(sel.l0Limit, std::numeric_limits<double>::infinity());
0134 BOOST_CHECK_EQUAL(sel.x0Process, std::numeric_limits<std::size_t>::max());
0135 BOOST_CHECK_EQUAL(sel.l0Process, std::numeric_limits<std::size_t>::max());
0136
0137
0138
0139 BOOST_CHECK(!l.runPointLike(f.rng, 0u, f.incoming, f.outgoing));
0140 BOOST_CHECK_EQUAL(f.outgoing.size(), 0u);
0141
0142 BOOST_CHECK(!l.runPointLike(f.rng, std::numeric_limits<std::size_t>::max(),
0143 f.incoming, f.outgoing));
0144 BOOST_CHECK_EQUAL(f.outgoing.size(), 0u);
0145 }
0146
0147 BOOST_AUTO_TEST_CASE(ContinuousSterile) {
0148 Fixture f;
0149 InteractionList<SterileContinuousProcess> l;
0150
0151
0152 BOOST_CHECK(!l.runContinuous(f.rng, f.slab, f.incoming, f.outgoing));
0153 }
0154
0155 BOOST_AUTO_TEST_CASE(ContinuousFatal) {
0156 Fixture f;
0157 InteractionList<FatalContinuousProcess> l;
0158
0159
0160 BOOST_CHECK(l.runContinuous(f.rng, f.slab, f.incoming, f.outgoing));
0161 }
0162
0163 BOOST_AUTO_TEST_CASE(ContinuousSterileFatal) {
0164 Fixture f;
0165 InteractionList<SterileContinuousProcess, FatalContinuousProcess> physicsList;
0166
0167
0168 BOOST_CHECK(physicsList.runContinuous(f.rng, f.slab, f.incoming, f.outgoing));
0169
0170 physicsList.disable<FatalContinuousProcess>();
0171 BOOST_CHECK(
0172 !physicsList.runContinuous(f.rng, f.slab, f.incoming, f.outgoing));
0173 }
0174
0175 BOOST_AUTO_TEST_CASE(PointLikeX0) {
0176 Fixture f;
0177 InteractionList<X0PointLikeProcess> l;
0178
0179
0180 auto sel = l.armPointLike(f.rng, f.incoming);
0181 BOOST_CHECK_EQUAL(sel.x0Limit, 0.5);
0182 BOOST_CHECK_EQUAL(sel.l0Limit, std::numeric_limits<double>::infinity());
0183 BOOST_CHECK_EQUAL(sel.x0Process, 0u);
0184 BOOST_CHECK_EQUAL(sel.l0Process, std::numeric_limits<std::size_t>::max());
0185
0186
0187 BOOST_CHECK(!l.runPointLike(f.rng, 0u, f.incoming, f.outgoing));
0188 BOOST_CHECK_EQUAL(f.outgoing.size(), 1u);
0189
0190 BOOST_CHECK(!l.runPointLike(f.rng, std::numeric_limits<std::size_t>::max(),
0191 f.incoming, f.outgoing));
0192 BOOST_CHECK_EQUAL(f.outgoing.size(), 1u);
0193 }
0194
0195 BOOST_AUTO_TEST_CASE(PointLikeL0) {
0196 Fixture f;
0197 InteractionList<L0PointLikeProcess> l;
0198
0199
0200 auto sel = l.armPointLike(f.rng, f.incoming);
0201 BOOST_CHECK_EQUAL(sel.x0Limit, std::numeric_limits<double>::infinity());
0202 BOOST_CHECK_EQUAL(sel.l0Limit, 1.5);
0203 BOOST_CHECK_EQUAL(sel.x0Process, std::numeric_limits<std::size_t>::max());
0204 BOOST_CHECK_EQUAL(sel.l0Process, 0u);
0205
0206
0207 BOOST_CHECK(l.runPointLike(f.rng, 0u, f.incoming, f.outgoing));
0208 BOOST_CHECK_EQUAL(f.outgoing.size(), 2u);
0209
0210 BOOST_CHECK(!l.runPointLike(f.rng, std::numeric_limits<std::size_t>::max(),
0211 f.incoming, f.outgoing));
0212 BOOST_CHECK_EQUAL(f.outgoing.size(), 2u);
0213 }
0214
0215 BOOST_AUTO_TEST_CASE(PointLikeX0L0) {
0216 Fixture f;
0217 InteractionList<X0PointLikeProcess, L0PointLikeProcess> l;
0218
0219
0220 auto sel = l.armPointLike(f.rng, f.incoming);
0221 BOOST_CHECK_EQUAL(sel.x0Limit, 0.5);
0222 BOOST_CHECK_EQUAL(sel.l0Limit, 1.5);
0223 BOOST_CHECK_EQUAL(sel.x0Process, 0u);
0224 BOOST_CHECK_EQUAL(sel.l0Process, 1u);
0225
0226
0227 BOOST_CHECK(!l.runPointLike(f.rng, 0u, f.incoming, f.outgoing));
0228 BOOST_CHECK_EQUAL(f.outgoing.size(), 1u);
0229
0230 BOOST_CHECK(l.runPointLike(f.rng, 1u, f.incoming, f.outgoing));
0231 BOOST_CHECK_EQUAL(f.outgoing.size(), 3u);
0232
0233 BOOST_CHECK(!l.runPointLike(f.rng, std::numeric_limits<std::size_t>::max(),
0234 f.incoming, f.outgoing));
0235 BOOST_CHECK_EQUAL(f.outgoing.size(), 3u);
0236 }
0237
0238
0239
0240 BOOST_AUTO_TEST_CASE(Disable) {
0241 Fixture f;
0242 InteractionList<SterileContinuousProcess, FatalContinuousProcess,
0243 X0PointLikeProcess, L0PointLikeProcess>
0244 l;
0245
0246
0247 BOOST_CHECK(l.runContinuous(f.rng, f.slab, f.incoming, f.outgoing));
0248
0249 l.disable<FatalContinuousProcess>();
0250 BOOST_CHECK(!l.runContinuous(f.rng, f.slab, f.incoming, f.outgoing));
0251
0252
0253 l.disable<X0PointLikeProcess>();
0254 {
0255 auto sel = l.armPointLike(f.rng, f.incoming);
0256 BOOST_CHECK_EQUAL(sel.x0Limit, std::numeric_limits<double>::infinity());
0257 BOOST_CHECK_EQUAL(sel.l0Limit, 1.5);
0258 BOOST_CHECK_EQUAL(sel.x0Process, std::numeric_limits<std::size_t>::max());
0259 BOOST_CHECK_EQUAL(sel.l0Process, 3u);
0260
0261
0262 f.outgoing.clear();
0263 BOOST_CHECK(!l.runPointLike(f.rng, 2u, f.incoming, f.outgoing));
0264 BOOST_CHECK_EQUAL(f.outgoing.size(), 0u);
0265
0266 BOOST_CHECK(l.runPointLike(f.rng, 3u, f.incoming, f.outgoing));
0267 BOOST_CHECK_EQUAL(f.outgoing.size(), 2u);
0268 }
0269
0270
0271 l.disable<L0PointLikeProcess>();
0272 {
0273 auto sel = l.armPointLike(f.rng, f.incoming);
0274 BOOST_CHECK_EQUAL(sel.x0Limit, std::numeric_limits<double>::infinity());
0275 BOOST_CHECK_EQUAL(sel.l0Limit, std::numeric_limits<double>::infinity());
0276 BOOST_CHECK_EQUAL(sel.x0Process, std::numeric_limits<std::size_t>::max());
0277 BOOST_CHECK_EQUAL(sel.l0Process, std::numeric_limits<std::size_t>::max());
0278
0279
0280 f.outgoing.clear();
0281 BOOST_CHECK(!l.runPointLike(f.rng, 2u, f.incoming, f.outgoing));
0282 BOOST_CHECK_EQUAL(f.outgoing.size(), 0u);
0283
0284 BOOST_CHECK(!l.runPointLike(f.rng, 3u, f.incoming, f.outgoing));
0285 BOOST_CHECK_EQUAL(f.outgoing.size(), 0u);
0286 }
0287
0288
0289 f.outgoing.clear();
0290 BOOST_CHECK(!l.runPointLike(f.rng, std::numeric_limits<std::size_t>::max(),
0291 f.incoming, f.outgoing));
0292 BOOST_CHECK_EQUAL(f.outgoing.size(), 0u);
0293 }
0294
0295 BOOST_AUTO_TEST_SUITE_END()
0296
0297 }