File indexing completed on 2025-01-18 09:12:33
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Direction.hpp"
0013 #include "Acts/Detector/DetectorVolume.hpp"
0014 #include "Acts/Detector/Portal.hpp"
0015 #include "Acts/Detector/PortalGenerators.hpp"
0016 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0017 #include "Acts/Geometry/GeometryContext.hpp"
0018 #include "Acts/Geometry/GeometryIdentifier.hpp"
0019 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0020 #include "Acts/Material/MaterialSlab.hpp"
0021 #include "Acts/Navigation/InternalNavigation.hpp"
0022 #include "Acts/Navigation/NavigationDelegates.hpp"
0023 #include "Acts/Navigation/NavigationState.hpp"
0024 #include "Acts/Surfaces/PlaneSurface.hpp"
0025 #include "Acts/Surfaces/RectangleBounds.hpp"
0026 #include "Acts/Surfaces/Surface.hpp"
0027
0028 #include <array>
0029 #include <memory>
0030 #include <stdexcept>
0031 #include <utility>
0032 #include <vector>
0033
0034 namespace Acts::Experimental {
0035
0036
0037 class LinkToVolumeImpl : public IExternalNavigation {
0038 public:
0039 std::shared_ptr<DetectorVolume> dVolume = nullptr;
0040
0041
0042 LinkToVolumeImpl(std::shared_ptr<DetectorVolume> dv)
0043 : dVolume(std::move(dv)) {}
0044
0045
0046
0047 void link(const GeometryContext& , NavigationState& nState) const {
0048 nState.currentVolume = dVolume.get();
0049 }
0050 };
0051
0052 }
0053
0054 using namespace Acts::Experimental;
0055
0056
0057 Acts::GeometryContext tContext;
0058
0059 BOOST_AUTO_TEST_SUITE(Detector)
0060
0061 BOOST_AUTO_TEST_CASE(PortalTest) {
0062 auto dTransform = Acts::Transform3::Identity();
0063 auto pGenerator = defaultPortalGenerator();
0064 auto volumeA = DetectorVolumeFactory::construct(
0065 pGenerator, tContext, "dummyA", dTransform,
0066 std::make_unique<Acts::CuboidVolumeBounds>(1, 1, 1),
0067 tryAllPortalsAndSurfaces());
0068 auto volumeB = DetectorVolumeFactory::construct(
0069 pGenerator, tContext, "dummyB", dTransform,
0070 std::make_unique<Acts::CuboidVolumeBounds>(1, 1, 1),
0071 tryAllPortalsAndSurfaces());
0072
0073
0074 auto rectangle = std::make_shared<Acts::RectangleBounds>(10., 100.);
0075 auto surface =
0076 Acts::Surface::makeShared<Acts::PlaneSurface>(dTransform, rectangle);
0077
0078
0079 auto portalA = std::make_shared<Portal>(surface);
0080
0081 BOOST_CHECK_EQUAL(&(portalA->surface()), surface.get());
0082
0083 portalA->assignGeometryId(Acts::GeometryIdentifier{5});
0084 BOOST_CHECK_EQUAL(portalA->surface().geometryId(),
0085 Acts::GeometryIdentifier{5});
0086
0087
0088 auto linkToAImpl = std::make_unique<const LinkToVolumeImpl>(volumeA);
0089 ExternalNavigationDelegate linkToA;
0090 linkToA.connect<&LinkToVolumeImpl::link>(std::move(linkToAImpl));
0091 portalA->assignPortalNavigation(Acts::Direction::Positive(),
0092 std::move(linkToA), {volumeA});
0093
0094 auto attachedDetectorVolumes = portalA->attachedDetectorVolumes();
0095 BOOST_CHECK(attachedDetectorVolumes[0u].empty());
0096 BOOST_CHECK_EQUAL(attachedDetectorVolumes[1u].size(), 1u);
0097 BOOST_CHECK_EQUAL(attachedDetectorVolumes[1u][0u], volumeA);
0098
0099 NavigationState nState;
0100 nState.position = Acts::Vector3(0., 0., 0.);
0101 nState.direction = Acts::Vector3(0., 0., 1.);
0102
0103 portalA->updateDetectorVolume(tContext, nState);
0104 BOOST_CHECK_EQUAL(nState.currentVolume, volumeA.get());
0105
0106 nState.direction = Acts::Vector3(0., 0., -1.);
0107 portalA->updateDetectorVolume(tContext, nState);
0108 BOOST_CHECK_EQUAL(nState.currentVolume, nullptr);
0109
0110 auto portalB = std::make_shared<Portal>(surface);
0111 ExternalNavigationDelegate linkToB;
0112 auto linkToBImpl = std::make_unique<const LinkToVolumeImpl>(volumeB);
0113 linkToB.connect<&LinkToVolumeImpl::link>(std::move(linkToBImpl));
0114 portalB->assignPortalNavigation(Acts::Direction::Negative(),
0115 std::move(linkToB), {volumeB});
0116
0117
0118 nState.direction = Acts::Vector3(0., 0., 1.);
0119 portalB->updateDetectorVolume(tContext, nState);
0120 BOOST_CHECK_EQUAL(nState.currentVolume, nullptr);
0121 nState.direction = Acts::Vector3(0., 0., -1.);
0122 portalB->updateDetectorVolume(tContext, nState);
0123 BOOST_CHECK_EQUAL(nState.currentVolume, volumeB.get());
0124
0125 Acts::GeometryContext gctx;
0126 BOOST_CHECK_EQUAL(portalA->surface().center(gctx),
0127 portalB->surface().center(gctx));
0128
0129
0130 BOOST_CHECK_EQUAL(portalA, Portal::fuse(portalA, portalA));
0131
0132
0133 portalA = Portal::fuse(portalA, portalB);
0134
0135 nState.direction = Acts::Vector3(0., 0., 1.);
0136 portalA->updateDetectorVolume(tContext, nState);
0137 BOOST_CHECK_EQUAL(nState.currentVolume, volumeA.get());
0138 nState.direction = Acts::Vector3(0., 0., -1.);
0139 portalA->updateDetectorVolume(tContext, nState);
0140 BOOST_CHECK_EQUAL(nState.currentVolume, volumeB.get());
0141
0142
0143 BOOST_CHECK_EQUAL(portalA->surface().center(gctx),
0144 portalB->surface().center(gctx));
0145
0146
0147 bool reached = false;
0148 const Portal* cportalB = portalB.get();
0149 cportalB->visitSurface([&reached](const auto* s) {
0150 if (s != nullptr) {
0151 reached = true;
0152 }
0153 });
0154 BOOST_CHECK(reached);
0155
0156
0157 struct SetMaterial {
0158
0159 std::shared_ptr<const Acts::HomogeneousSurfaceMaterial> material =
0160 std::make_shared<Acts::HomogeneousSurfaceMaterial>(Acts::MaterialSlab(
0161 Acts::Material::fromMolarDensity(1., 2., 3., 4., 5.), 1.));
0162
0163 void operator()(Acts::Surface* s) {
0164 if (s != nullptr) {
0165 s->assignSurfaceMaterial(material);
0166 }
0167 }
0168 };
0169
0170 SetMaterial setMaterial;
0171 BOOST_CHECK(portalA->surface().surfaceMaterial() == nullptr);
0172 portalA->visitMutableSurface(setMaterial);
0173 BOOST_CHECK(portalA->surface().surfaceMaterial() ==
0174 setMaterial.material.get());
0175 }
0176
0177 BOOST_AUTO_TEST_CASE(PortalMaterialTest) {
0178
0179 auto dTransform = Acts::Transform3::Identity();
0180 auto pGenerator = defaultPortalGenerator();
0181 auto volumeA = DetectorVolumeFactory::construct(
0182 pGenerator, tContext, "dummyA", dTransform,
0183 std::make_unique<Acts::CuboidVolumeBounds>(1, 1, 1),
0184 tryAllPortalsAndSurfaces());
0185 auto volumeB = DetectorVolumeFactory::construct(
0186 pGenerator, tContext, "dummyB", dTransform,
0187 std::make_unique<Acts::CuboidVolumeBounds>(1, 1, 1),
0188 tryAllPortalsAndSurfaces());
0189
0190
0191 auto materialSlab = Acts::MaterialSlab(
0192 Acts::Material::fromMolarDensity(1., 2., 3., 4., 5.), 1.);
0193 auto materialA =
0194 std::make_shared<Acts::HomogeneousSurfaceMaterial>(materialSlab);
0195 auto materialB =
0196 std::make_shared<Acts::HomogeneousSurfaceMaterial>(materialSlab);
0197
0198
0199 auto rectangle = std::make_shared<Acts::RectangleBounds>(10., 100.);
0200
0201 auto surfaceA = Acts::Surface::makeShared<Acts::PlaneSurface>(
0202 Acts::Transform3::Identity(), rectangle);
0203 surfaceA->assignSurfaceMaterial(materialA);
0204 auto portalA = std::make_shared<Portal>(surfaceA);
0205
0206 ExternalNavigationDelegate linkToA;
0207 auto linkToAImpl = std::make_unique<const LinkToVolumeImpl>(volumeA);
0208 linkToA.connect<&LinkToVolumeImpl::link>(std::move(linkToAImpl));
0209 portalA->assignPortalNavigation(Acts::Direction::Positive(),
0210 std::move(linkToA), {volumeA});
0211
0212 auto surfaceB = Acts::Surface::makeShared<Acts::PlaneSurface>(
0213 Acts::Transform3::Identity(), rectangle);
0214 auto portalB = std::make_shared<Portal>(surfaceB);
0215 ExternalNavigationDelegate linkToB;
0216 auto linkToBImpl = std::make_unique<const LinkToVolumeImpl>(volumeB);
0217 linkToB.connect<&LinkToVolumeImpl::link>(std::move(linkToBImpl));
0218 portalB->assignPortalNavigation(Acts::Direction::Negative(),
0219 std::move(linkToB), {volumeB});
0220
0221
0222
0223 portalA = Portal::fuse(portalA, portalB);
0224 BOOST_CHECK_EQUAL(portalA->surface().surfaceMaterial(), materialA.get());
0225
0226
0227 portalB = std::make_shared<Portal>(surfaceB);
0228 ExternalNavigationDelegate linkToB2;
0229 auto linkToB2Impl = std::make_unique<const LinkToVolumeImpl>(volumeB);
0230 linkToB2.connect<&LinkToVolumeImpl::link>(std::move(linkToB2Impl));
0231 portalB->assignPortalNavigation(Acts::Direction::Negative(),
0232 std::move(linkToB2), {volumeB});
0233
0234
0235
0236 BOOST_REQUIRE_NE(portalA, portalB);
0237
0238
0239 BOOST_CHECK_THROW(Portal::fuse(portalB, portalA), std::invalid_argument);
0240
0241 portalA->assignPortalNavigation(Acts::Direction::Negative(),
0242 ExternalNavigationDelegate{}, {});
0243
0244 portalB = Portal::fuse(portalB, portalA);
0245 BOOST_CHECK_EQUAL(portalB->surface().surfaceMaterial(), materialA.get());
0246
0247
0248 portalA = std::make_shared<Portal>(surfaceA);
0249 ExternalNavigationDelegate linkToA2;
0250 auto linkToA2Impl = std::make_unique<const LinkToVolumeImpl>(volumeA);
0251 linkToA2.connect<&LinkToVolumeImpl::link>(std::move(linkToA2Impl));
0252 portalA->assignPortalNavigation(Acts::Direction::Positive(),
0253 std::move(linkToA2), {volumeA});
0254
0255 surfaceB->assignSurfaceMaterial(materialB);
0256 portalB = std::make_shared<Portal>(surfaceB);
0257 ExternalNavigationDelegate linkToB3;
0258 auto linkToB3Impl = std::make_unique<const LinkToVolumeImpl>(volumeB);
0259 linkToB3.connect<&LinkToVolumeImpl::link>(std::move(linkToB3Impl));
0260 portalB->assignPortalNavigation(Acts::Direction::Negative(),
0261 std::move(linkToB3), {volumeB});
0262
0263
0264 BOOST_CHECK_THROW(Portal::fuse(portalA, portalB), std::runtime_error);
0265
0266 BOOST_CHECK_THROW(Portal::fuse(portalB, portalA), std::runtime_error);
0267 }
0268
0269 BOOST_AUTO_TEST_SUITE_END()