File indexing completed on 2025-01-18 09:12:41
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/tools/context.hpp>
0010 #include <boost/test/tools/old/interface.hpp>
0011 #include <boost/test/unit_test.hpp>
0012 #include <boost/test/unit_test_suite.hpp>
0013
0014 #include "Acts/Definitions/Units.hpp"
0015 #include "Acts/Geometry/CompositePortalLink.hpp"
0016 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0017 #include "Acts/Geometry/GeometryContext.hpp"
0018 #include "Acts/Geometry/GridPortalLink.hpp"
0019 #include "Acts/Geometry/Portal.hpp"
0020 #include "Acts/Geometry/TrackingVolume.hpp"
0021 #include "Acts/Geometry/TrivialPortalLink.hpp"
0022 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0023 #include "Acts/Surfaces/CylinderSurface.hpp"
0024 #include "Acts/Surfaces/DiscSurface.hpp"
0025 #include "Acts/Surfaces/RadialBounds.hpp"
0026 #include "Acts/Surfaces/Surface.hpp"
0027 #include "Acts/Surfaces/SurfaceMergingException.hpp"
0028 #include "Acts/Utilities/BinningType.hpp"
0029 #include "Acts/Utilities/ThrowAssert.hpp"
0030
0031 #include <stdexcept>
0032
0033 using namespace Acts::UnitLiterals;
0034
0035 namespace Acts::Test {
0036
0037 auto logger = Acts::getDefaultLogger("UnitTests", Acts::Logging::VERBOSE);
0038
0039 struct Fixture {
0040 Logging::Level m_level;
0041 Fixture() {
0042 m_level = Acts::Logging::getFailureThreshold();
0043 Acts::Logging::setFailureThreshold(Acts::Logging::FATAL);
0044 }
0045
0046 ~Fixture() { Acts::Logging::setFailureThreshold(m_level); }
0047 };
0048
0049 std::shared_ptr<TrackingVolume> makeDummyVolume() {
0050 return std::make_shared<TrackingVolume>(
0051 Transform3::Identity(),
0052 std::make_shared<CylinderVolumeBounds>(30_mm, 40_mm, 100_mm));
0053 }
0054
0055 GeometryContext gctx;
0056
0057 BOOST_FIXTURE_TEST_SUITE(Geometry, Fixture)
0058
0059 BOOST_AUTO_TEST_SUITE(Portals)
0060 BOOST_AUTO_TEST_SUITE(Merging)
0061
0062 BOOST_AUTO_TEST_CASE(Cylinder) {
0063 auto vol1 = makeDummyVolume();
0064 vol1->setVolumeName("vol1");
0065 auto vol2 = makeDummyVolume();
0066 vol2->setVolumeName("vol2");
0067
0068 auto cyl1 = Surface::makeShared<CylinderSurface>(
0069 Transform3{Translation3{Vector3::UnitZ() * -100_mm}}, 50_mm, 100_mm);
0070
0071 auto cyl2 = Surface::makeShared<CylinderSurface>(
0072 Transform3{Translation3{Vector3::UnitZ() * 100_mm}}, 50_mm, 100_mm);
0073
0074 Portal portal1{Direction::AlongNormal(),
0075 std::make_unique<TrivialPortalLink>(cyl1, *vol1)};
0076 BOOST_CHECK(portal1.isValid());
0077
0078 BOOST_CHECK_EQUAL(
0079 portal1
0080 .resolveVolume(gctx, Vector3{50_mm, 0_mm, -100_mm}, Vector3::UnitX())
0081 .value(),
0082 vol1.get());
0083
0084 BOOST_CHECK_EQUAL(
0085 portal1
0086 .resolveVolume(gctx, Vector3{50_mm, 0_mm, -100_mm}, -Vector3::UnitX())
0087 .value(),
0088 nullptr);
0089
0090 Portal portal2{Direction::AlongNormal(), cyl2, *vol2};
0091 BOOST_CHECK(portal2.isValid());
0092
0093 BOOST_CHECK_EQUAL(
0094 portal2
0095 .resolveVolume(gctx, Vector3{50_mm, 0_mm, 100_mm}, -Vector3::UnitX())
0096 .value(),
0097 nullptr);
0098
0099 BOOST_CHECK_EQUAL(
0100 portal2
0101 .resolveVolume(gctx, Vector3{50_mm, 0_mm, 100_mm}, Vector3::UnitX())
0102 .value(),
0103 vol2.get());
0104
0105 Portal portal3{gctx, std::make_unique<TrivialPortalLink>(cyl2, *vol2),
0106 nullptr};
0107 BOOST_CHECK(portal3.isValid());
0108
0109 BOOST_CHECK_NE(portal3.getLink(Direction::AlongNormal()), nullptr);
0110 BOOST_CHECK_EQUAL(portal3.getLink(Direction::OppositeNormal()), nullptr);
0111
0112 Portal portal4{gctx, nullptr,
0113 std::make_unique<TrivialPortalLink>(cyl2, *vol2)};
0114 BOOST_CHECK(portal4.isValid());
0115
0116 BOOST_CHECK_EQUAL(portal4.getLink(Direction::AlongNormal()), nullptr);
0117 BOOST_CHECK_NE(portal4.getLink(Direction::OppositeNormal()), nullptr);
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129 BOOST_CHECK_THROW(
0130 Portal::merge(gctx, portal1, portal4, AxisDirection::AxisZ, *logger),
0131 PortalMergingException);
0132
0133
0134
0135 BOOST_CHECK(portal1.isValid());
0136 BOOST_CHECK(portal2.isValid());
0137
0138 BOOST_CHECK_EQUAL(
0139 portal2.resolveVolume(gctx, Vector3{50_mm, 0_mm, 50_mm}, Vector3::UnitX())
0140 .value(),
0141 vol2.get());
0142
0143 BOOST_CHECK_EQUAL(
0144 portal2
0145 .resolveVolume(gctx, Vector3{50_mm, 0_mm, 50_mm}, -Vector3::UnitX())
0146 .value(),
0147 nullptr);
0148
0149
0150 BOOST_CHECK_THROW(
0151 Portal::merge(gctx, portal1, portal2, AxisDirection::AxisRPhi, *logger),
0152 SurfaceMergingException);
0153
0154
0155
0156 BOOST_CHECK(!portal1.isValid());
0157 BOOST_CHECK(!portal2.isValid());
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167 portal1 = Portal{gctx, {.alongNormal = {cyl1, *vol1}}};
0168 portal2 = Portal{gctx, {.alongNormal = {cyl2, *vol2}}};
0169
0170 Portal merged12 =
0171 Portal::merge(gctx, portal1, portal2, AxisDirection::AxisZ, *logger);
0172 BOOST_CHECK_NE(merged12.getLink(Direction::AlongNormal()), nullptr);
0173 BOOST_CHECK_EQUAL(merged12.getLink(Direction::OppositeNormal()), nullptr);
0174
0175 auto composite12 = dynamic_cast<const CompositePortalLink*>(
0176 merged12.getLink(Direction::AlongNormal()));
0177 BOOST_REQUIRE_NE(composite12, nullptr);
0178
0179 BOOST_CHECK_EQUAL(
0180 merged12
0181 .resolveVolume(gctx, Vector3{50_mm, 0_mm, -50_mm}, Vector3::UnitX())
0182 .value(),
0183 vol1.get());
0184
0185 BOOST_CHECK_EQUAL(
0186 merged12
0187 .resolveVolume(gctx, Vector3{50_mm, 0_mm, 50_mm}, Vector3::UnitX())
0188 .value(),
0189 vol2.get());
0190
0191 BOOST_CHECK_EQUAL(
0192 merged12
0193 .resolveVolume(gctx, Vector3{50_mm, 0_mm, -50_mm}, -Vector3::UnitX())
0194 .value(),
0195 nullptr);
0196
0197 BOOST_CHECK_EQUAL(
0198 merged12
0199 .resolveVolume(gctx, Vector3{50_mm, 0_mm, 50_mm}, -Vector3::UnitX())
0200 .value(),
0201 nullptr);
0202
0203 portal1 = Portal{gctx, {.alongNormal = {cyl1, *vol1}}};
0204
0205
0206 BOOST_CHECK_THROW(
0207 Portal::merge(gctx, portal1, portal1, AxisDirection::AxisZ, *logger),
0208 PortalMergingException);
0209
0210
0211 portal1 = Portal{gctx, {.alongNormal = {cyl1, *vol1}}};
0212 portal2 = Portal{gctx, {.alongNormal = {cyl1, *vol2}}};
0213 BOOST_CHECK_THROW(
0214 Portal::merge(gctx, portal1, portal2, AxisDirection::AxisZ, *logger),
0215 AssertionFailureException);
0216
0217
0218 auto material =
0219 std::make_shared<HomogeneousSurfaceMaterial>(MaterialSlab{});
0220 cyl2->assignSurfaceMaterial(material);
0221 portal1 = Portal{gctx, {.alongNormal = {cyl1, *vol1}}};
0222 portal2 = Portal{gctx, {.alongNormal = {cyl2, *vol2}}};
0223 BOOST_CHECK_THROW(
0224 Portal::merge(gctx, portal1, portal2, AxisDirection::AxisZ, *logger),
0225 PortalMergingException);
0226 }
0227
0228 BOOST_AUTO_TEST_CASE(Disc) {
0229 auto vol1 = makeDummyVolume();
0230 vol1->setVolumeName("vol1");
0231 auto vol2 = makeDummyVolume();
0232 vol2->setVolumeName("vol2");
0233 auto vol3 = makeDummyVolume();
0234 vol3->setVolumeName("vol3");
0235 auto vol4 = makeDummyVolume();
0236 vol4->setVolumeName("vol4");
0237
0238 auto disc1 = Surface::makeShared<DiscSurface>(
0239 Transform3::Identity(), std::make_shared<RadialBounds>(50_mm, 100_mm));
0240
0241 auto disc2 = Surface::makeShared<DiscSurface>(
0242 Transform3::Identity(), std::make_shared<RadialBounds>(100_mm, 150_mm));
0243
0244 Portal portal1{
0245 gctx, {.alongNormal = {disc1, *vol1}, .oppositeNormal = {disc1, *vol2}}};
0246
0247 Portal portal2{
0248 gctx, {.alongNormal = {disc2, *vol3}, .oppositeNormal = {disc2, *vol4}}};
0249
0250 BOOST_CHECK(portal1.isValid());
0251 BOOST_CHECK(portal2.isValid());
0252
0253 BOOST_CHECK_EQUAL(
0254 portal1.resolveVolume(gctx, Vector3{55_mm, 0_mm, 0_mm}, Vector3::UnitZ())
0255 .value(),
0256 vol1.get());
0257 BOOST_CHECK_EQUAL(
0258 portal1.resolveVolume(gctx, Vector3{55_mm, 0_mm, 0_mm}, -Vector3::UnitZ())
0259 .value(),
0260 vol2.get());
0261
0262 BOOST_CHECK_EQUAL(
0263 portal2.resolveVolume(gctx, Vector3{105_mm, 0_mm, 0_mm}, Vector3::UnitZ())
0264 .value(),
0265 vol3.get());
0266 BOOST_CHECK_EQUAL(
0267 portal2
0268 .resolveVolume(gctx, Vector3{105_mm, 0_mm, 0_mm}, -Vector3::UnitZ())
0269 .value(),
0270 vol4.get());
0271
0272 BOOST_CHECK_THROW(
0273 Portal::merge(gctx, portal1, portal2, AxisDirection::AxisZ, *logger),
0274 AssertionFailureException);
0275
0276 BOOST_CHECK(portal1.isValid());
0277 BOOST_CHECK(portal2.isValid());
0278
0279 BOOST_CHECK_THROW(
0280 Portal::merge(gctx, portal1, portal2, AxisDirection::AxisPhi, *logger),
0281 SurfaceMergingException);
0282
0283
0284
0285 BOOST_CHECK(!portal1.isValid());
0286 BOOST_CHECK(!portal2.isValid());
0287
0288
0289 portal1 = Portal{
0290 gctx, {.alongNormal = {disc1, *vol1}, .oppositeNormal = {disc1, *vol2}}};
0291
0292 portal2 = Portal{
0293 gctx, {.alongNormal = {disc2, *vol3}, .oppositeNormal = {disc2, *vol4}}};
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304 Portal merged12 =
0305 Portal::merge(gctx, portal1, portal2, AxisDirection::AxisR, *logger);
0306
0307 BOOST_CHECK_EQUAL(
0308 merged12.resolveVolume(gctx, Vector3{55_mm, 0_mm, 0_mm}, Vector3::UnitZ())
0309 .value(),
0310 vol1.get());
0311 BOOST_CHECK_EQUAL(
0312 merged12
0313 .resolveVolume(gctx, Vector3{55_mm, 0_mm, 0_mm}, -Vector3::UnitZ())
0314 .value(),
0315 vol2.get());
0316
0317 BOOST_CHECK_EQUAL(
0318 merged12
0319 .resolveVolume(gctx, Vector3{105_mm, 0_mm, 0_mm}, Vector3::UnitZ())
0320 .value(),
0321 vol3.get());
0322 BOOST_CHECK_EQUAL(
0323 merged12
0324 .resolveVolume(gctx, Vector3{105_mm, 0_mm, 0_mm}, -Vector3::UnitZ())
0325 .value(),
0326 vol4.get());
0327
0328
0329 auto material =
0330 std::make_shared<HomogeneousSurfaceMaterial>(MaterialSlab{});
0331 disc2->assignSurfaceMaterial(material);
0332 portal1 = Portal{
0333 gctx, {.alongNormal = {disc1, *vol1}, .oppositeNormal = {disc1, *vol2}}};
0334 portal2 = Portal{
0335 gctx, {.alongNormal = {disc2, *vol3}, .oppositeNormal = {disc2, *vol4}}};
0336 BOOST_CHECK_THROW(
0337 Portal::merge(gctx, portal1, portal2, AxisDirection::AxisR, *logger),
0338 PortalMergingException);
0339 }
0340
0341 BOOST_AUTO_TEST_SUITE_END()
0342
0343 BOOST_AUTO_TEST_SUITE(Fusing)
0344
0345 BOOST_AUTO_TEST_CASE(Separated) {
0346 auto vol1 = makeDummyVolume();
0347 vol1->setVolumeName("vol1");
0348 auto vol2 = makeDummyVolume();
0349 vol2->setVolumeName("vol2");
0350
0351 auto cyl1 = Surface::makeShared<CylinderSurface>(Transform3::Identity(),
0352 50_mm, 100_mm);
0353
0354 auto cyl2 = Surface::makeShared<CylinderSurface>(Transform3::Identity(),
0355 60_mm, 100_mm);
0356
0357 Portal portal1{gctx, {.oppositeNormal = {cyl1, *vol1}}};
0358
0359 Portal portal2{gctx, {.alongNormal = {cyl2, *vol2}}};
0360
0361 BOOST_CHECK(portal1.isValid());
0362 BOOST_CHECK(portal2.isValid());
0363
0364
0365 BOOST_CHECK_THROW(Portal::fuse(gctx, portal1, portal2, *logger),
0366 PortalFusingException);
0367
0368 BOOST_CHECK(portal1.isValid());
0369 BOOST_CHECK(portal2.isValid());
0370
0371
0372 BOOST_CHECK_THROW(
0373 portal1.setLink(gctx, Direction::AlongNormal(), cyl2, *vol2),
0374 PortalFusingException);
0375 BOOST_CHECK_EQUAL(portal1.getLink(Direction::AlongNormal()), nullptr);
0376
0377 Portal portal1b{gctx, {.oppositeNormal = {cyl1, *vol1}}};
0378 BOOST_CHECK(portal1b.isValid());
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388 BOOST_CHECK_THROW(Portal::fuse(gctx, portal1, portal1b, *logger),
0389 PortalFusingException);
0390 BOOST_CHECK(portal1.isValid());
0391 BOOST_CHECK(portal1b.isValid());
0392
0393 auto disc1 = Surface::makeShared<DiscSurface>(
0394 Transform3::Identity(), std::make_shared<RadialBounds>(50_mm, 100_mm));
0395
0396 auto disc2 = Surface::makeShared<DiscSurface>(
0397 Transform3{Translation3{Vector3{0, 0, 5_mm}}},
0398 std::make_shared<RadialBounds>(50_mm, 100_mm));
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408 Portal portal2b{gctx, {.alongNormal = {disc2, *vol2}}};
0409
0410 BOOST_CHECK_THROW(Portal::fuse(gctx, portal2, portal2b, *logger),
0411 PortalFusingException);
0412 BOOST_CHECK(portal1.isValid());
0413 BOOST_CHECK(portal2.isValid());
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423 Portal portal2c{
0424 gctx, {.alongNormal = {disc2, *vol1}, .oppositeNormal = {disc2, *vol2}}};
0425 BOOST_CHECK(portal2c.isValid());
0426
0427 BOOST_CHECK_THROW(Portal::fuse(gctx, portal2, portal2c, *logger),
0428 PortalFusingException);
0429 BOOST_CHECK(portal2.isValid());
0430 BOOST_CHECK(portal2c.isValid());
0431 }
0432
0433 BOOST_AUTO_TEST_CASE(Success) {
0434 auto vol1 = makeDummyVolume();
0435 vol1->setVolumeName("vol1");
0436 auto vol2 = makeDummyVolume();
0437 vol2->setVolumeName("vol2");
0438
0439 auto cyl1 = Surface::makeShared<CylinderSurface>(Transform3::Identity(),
0440 50_mm, 100_mm);
0441
0442 auto cyl2 = Surface::makeShared<CylinderSurface>(Transform3::Identity(),
0443 50_mm, 100_mm);
0444
0445 BOOST_CHECK(*cyl1 == *cyl2);
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455 Portal portal1{gctx, {.oppositeNormal = {cyl1, *vol1}}};
0456 BOOST_CHECK_EQUAL(&portal1.getLink(Direction::OppositeNormal())->surface(),
0457 cyl1.get());
0458
0459 Portal portal2{gctx, {.alongNormal = {cyl2, *vol2}}};
0460
0461 BOOST_CHECK(portal1.isValid());
0462 BOOST_CHECK(portal2.isValid());
0463
0464 Portal portal3 = Portal::fuse(gctx, portal1, portal2, *logger);
0465
0466 BOOST_CHECK(!portal1.isValid());
0467 BOOST_CHECK(!portal2.isValid());
0468 BOOST_CHECK(portal3.isValid());
0469
0470 BOOST_CHECK_EQUAL(portal3.surface().surfaceMaterial(), nullptr);
0471
0472
0473 BOOST_CHECK_EQUAL(&portal3.surface(), cyl2.get());
0474
0475 BOOST_CHECK_EQUAL(&portal3.getLink(Direction::OppositeNormal())->surface(),
0476 cyl2.get());
0477 }
0478
0479 BOOST_AUTO_TEST_CASE(Material) {
0480 auto vol1 = makeDummyVolume();
0481 auto vol2 = makeDummyVolume();
0482
0483 auto cyl1 = Surface::makeShared<CylinderSurface>(Transform3::Identity(),
0484 50_mm, 100_mm);
0485
0486 auto cyl2 = Surface::makeShared<CylinderSurface>(Transform3::Identity(),
0487 50_mm, 100_mm);
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497 Portal portal1{gctx, {.oppositeNormal = {cyl1, *vol1}}};
0498 Portal portal2{gctx, {.alongNormal = {cyl2, *vol2}}};
0499
0500 auto material =
0501 std::make_shared<HomogeneousSurfaceMaterial>(MaterialSlab{});
0502
0503 cyl1->assignSurfaceMaterial(material);
0504
0505 Portal portal12 = Portal::fuse(gctx, portal1, portal2, *logger);
0506
0507
0508 BOOST_CHECK_EQUAL(&portal12.surface(), cyl1.get());
0509 BOOST_CHECK_EQUAL(portal12.surface().surfaceMaterial(), material.get());
0510
0511
0512 portal1 = Portal{gctx, {.oppositeNormal = {cyl1, *vol1}}};
0513 portal2 = Portal{gctx, {.alongNormal = {cyl2, *vol2}}};
0514 cyl2->assignSurfaceMaterial(material);
0515
0516
0517 BOOST_CHECK_THROW(Portal::fuse(gctx, portal1, portal2, *logger),
0518 PortalFusingException);
0519
0520 BOOST_CHECK(portal1.isValid());
0521 BOOST_CHECK(portal2.isValid());
0522
0523 cyl1->assignSurfaceMaterial(nullptr);
0524
0525 portal12 = Portal::fuse(gctx, portal1, portal2, *logger);
0526
0527
0528 BOOST_CHECK_EQUAL(&portal12.surface(), cyl2.get());
0529 BOOST_CHECK_EQUAL(portal12.surface().surfaceMaterial(), material.get());
0530 }
0531
0532 BOOST_AUTO_TEST_CASE(GridCreationOnFuse) {
0533 Transform3 base = Transform3::Identity();
0534
0535 auto vol1 = std::make_shared<TrackingVolume>(
0536 base, std::make_shared<CylinderVolumeBounds>(30_mm, 40_mm, 100_mm));
0537
0538 auto vol2 = std::make_shared<TrackingVolume>(
0539 base, std::make_shared<CylinderVolumeBounds>(30_mm, 40_mm, 100_mm));
0540
0541 auto vol3 = std::make_shared<TrackingVolume>(
0542 base, std::make_shared<CylinderVolumeBounds>(40_mm, 50_mm, 100_mm));
0543
0544 auto vol4 = std::make_shared<TrackingVolume>(
0545 base, std::make_shared<CylinderVolumeBounds>(40_mm, 50_mm, 100_mm));
0546
0547 auto disc1 =
0548 Surface::makeShared<DiscSurface>(Transform3::Identity(), 30_mm, 60_mm);
0549
0550 auto disc2 =
0551 Surface::makeShared<DiscSurface>(Transform3::Identity(), 60_mm, 90_mm);
0552
0553 auto disc3 =
0554 Surface::makeShared<DiscSurface>(Transform3::Identity(), 90_mm, 120_mm);
0555
0556 auto trivial1 = std::make_unique<TrivialPortalLink>(disc1, *vol1);
0557 BOOST_REQUIRE(trivial1);
0558 auto trivial2 = std::make_unique<TrivialPortalLink>(disc2, *vol2);
0559 BOOST_REQUIRE(trivial2);
0560 auto trivial3 = std::make_unique<TrivialPortalLink>(disc3, *vol3);
0561 BOOST_REQUIRE(trivial3);
0562
0563 std::vector<std::unique_ptr<PortalLinkBase>> links;
0564 links.push_back(std::move(trivial1));
0565 links.push_back(std::move(trivial2));
0566 links.push_back(std::move(trivial3));
0567
0568 auto composite = std::make_unique<CompositePortalLink>(std::move(links),
0569 AxisDirection::AxisR);
0570
0571 auto discOpposite =
0572 Surface::makeShared<DiscSurface>(Transform3::Identity(), 30_mm, 120_mm);
0573
0574 auto trivialOpposite =
0575 std::make_unique<TrivialPortalLink>(discOpposite, *vol4);
0576
0577 Portal aPortal{gctx, std::move(composite), nullptr};
0578 Portal bPortal{gctx, nullptr, std::move(trivialOpposite)};
0579
0580 Portal fused = Portal::fuse(gctx, aPortal, bPortal, *logger);
0581
0582 BOOST_CHECK_NE(dynamic_cast<const TrivialPortalLink*>(
0583 fused.getLink(Direction::OppositeNormal())),
0584 nullptr);
0585
0586 const auto* grid = dynamic_cast<const GridPortalLink*>(
0587 fused.getLink(Direction::AlongNormal()));
0588 BOOST_REQUIRE_NE(grid, nullptr);
0589
0590 BOOST_CHECK_EQUAL(grid->grid().axes().front()->getNBins(), 3);
0591 }
0592
0593 BOOST_AUTO_TEST_SUITE_END()
0594
0595 BOOST_AUTO_TEST_CASE(Construction) {
0596 auto vol1 = makeDummyVolume();
0597
0598
0599 auto disc1 = Surface::makeShared<DiscSurface>(
0600 Transform3::Identity(), std::make_shared<RadialBounds>(50_mm, 100_mm));
0601
0602 auto disc2 = Surface::makeShared<DiscSurface>(
0603 Transform3{Translation3{Vector3{0, 0, 5_mm}}},
0604 std::make_shared<RadialBounds>(50_mm, 100_mm));
0605
0606 BOOST_CHECK_THROW(std::make_unique<Portal>(
0607 gctx, std::make_unique<TrivialPortalLink>(disc1, *vol1),
0608 std::make_unique<TrivialPortalLink>(disc2, *vol1)),
0609 PortalFusingException);
0610
0611 BOOST_CHECK_THROW((Portal{gctx, nullptr, nullptr}), std::invalid_argument);
0612 BOOST_CHECK_THROW(Portal(gctx, {}), std::invalid_argument);
0613 }
0614
0615 BOOST_AUTO_TEST_CASE(InvalidConstruction) {
0616 BOOST_CHECK_THROW(Portal(Direction::AlongNormal(), nullptr),
0617 std::invalid_argument);
0618
0619 auto vol1 = makeDummyVolume();
0620
0621 BOOST_CHECK_THROW(Portal(Direction::AlongNormal(), nullptr, *vol1),
0622 std::invalid_argument);
0623
0624 auto disc1 = Surface::makeShared<DiscSurface>(
0625 Transform3::Identity(), std::make_shared<RadialBounds>(50_mm, 100_mm));
0626 Portal portal(Direction::AlongNormal(), disc1, *vol1);
0627
0628 BOOST_CHECK_THROW(portal.setLink(gctx, Direction::AlongNormal(), nullptr),
0629 std::invalid_argument);
0630 }
0631
0632 BOOST_AUTO_TEST_CASE(PortalFill) {
0633 auto vol1 = makeDummyVolume();
0634 auto vol2 = makeDummyVolume();
0635
0636 auto cyl1 = Surface::makeShared<CylinderSurface>(Transform3::Identity(),
0637 50_mm, 100_mm);
0638
0639 Portal portal1{gctx, {.oppositeNormal = {cyl1, *vol1}}};
0640 Portal portal2{gctx, {.alongNormal = {cyl1, *vol2}}};
0641
0642
0643 Portal::fuse(gctx, portal1, portal2, *logger);
0644
0645 BOOST_CHECK_THROW(portal1.fill(*vol2), std::logic_error);
0646
0647 portal1 = Portal{gctx, {.oppositeNormal = {cyl1, *vol1}}};
0648 portal2 = Portal{gctx, {.alongNormal = {cyl1, *vol2}}};
0649
0650 BOOST_CHECK_EQUAL(portal1.getLink(Direction::AlongNormal()), nullptr);
0651 BOOST_CHECK_NE(portal1.getLink(Direction::OppositeNormal()), nullptr);
0652
0653 portal1.fill(*vol2);
0654 BOOST_CHECK_NE(portal1.getLink(Direction::AlongNormal()), nullptr);
0655 BOOST_CHECK_NE(portal1.getLink(Direction::OppositeNormal()), nullptr);
0656
0657 BOOST_CHECK_THROW(portal1.fill(*vol2), std::logic_error);
0658 }
0659
0660 BOOST_AUTO_TEST_SUITE_END()
0661
0662 BOOST_AUTO_TEST_SUITE_END()
0663
0664 }