File indexing completed on 2025-01-18 09:12:36
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/data/test_case.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/Blueprint.hpp"
0016 #include "Acts/Geometry/BlueprintNode.hpp"
0017 #include "Acts/Geometry/CylinderContainerBlueprintNode.hpp"
0018 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0019 #include "Acts/Geometry/CylinderVolumeStack.hpp"
0020 #include "Acts/Geometry/GeometryContext.hpp"
0021 #include "Acts/Geometry/LayerBlueprintNode.hpp"
0022 #include "Acts/Geometry/MaterialDesignatorBlueprintNode.hpp"
0023 #include "Acts/Geometry/StaticBlueprintNode.hpp"
0024 #include "Acts/Geometry/TrackingVolume.hpp"
0025 #include "Acts/Material/BinnedSurfaceMaterial.hpp"
0026 #include "Acts/Material/ProtoSurfaceMaterial.hpp"
0027 #include "Acts/Surfaces/RectangleBounds.hpp"
0028 #include "Acts/Tests/CommonHelpers/DetectorElementStub.hpp"
0029 #include "Acts/Utilities/BinningType.hpp"
0030 #include "Acts/Utilities/Logger.hpp"
0031
0032 #include <fstream>
0033 #include <stdexcept>
0034 #include <vector>
0035
0036 using namespace Acts::UnitLiterals;
0037
0038 namespace Acts::Test {
0039
0040 auto logger = Acts::getDefaultLogger("UnitTests", Acts::Logging::INFO);
0041
0042 GeometryContext gctx;
0043
0044 namespace {
0045
0046 auto nameLookup(const TrackingGeometry& geo) {
0047 return [&](const std::string& name) -> const TrackingVolume& {
0048 const TrackingVolume* volume = nullptr;
0049
0050 geo.visitVolumes([&](const TrackingVolume* v) {
0051 if (v->volumeName() == name) {
0052 volume = v;
0053 }
0054 });
0055
0056 if (volume == nullptr) {
0057 throw std::runtime_error("Volume not found: " + name);
0058 }
0059 return *volume;
0060 };
0061 }
0062
0063 std::size_t countVolumes(const TrackingGeometry& geo) {
0064 std::size_t nVolumes = 0;
0065 geo.visitVolumes([&](const TrackingVolume* ) { nVolumes++; });
0066 return nVolumes;
0067 }
0068
0069 }
0070
0071 BOOST_AUTO_TEST_SUITE(Geometry);
0072
0073 BOOST_AUTO_TEST_SUITE(BlueprintNodeTest);
0074
0075 BOOST_AUTO_TEST_CASE(InvalidRoot) {
0076 Logging::ScopedFailureThreshold threshold{Logging::Level::FATAL};
0077
0078 Blueprint::Config cfg;
0079 Blueprint root{cfg};
0080 BOOST_CHECK_THROW(root.construct({}, gctx, *logger), std::logic_error);
0081
0082
0083 auto cylBounds = std::make_shared<CylinderVolumeBounds>(10_mm, 20_mm, 100_mm);
0084 root.addChild(
0085 std::make_unique<StaticBlueprintNode>(std::make_unique<TrackingVolume>(
0086 Transform3::Identity(), cylBounds, "child1")));
0087 root.addChild(
0088 std::make_unique<StaticBlueprintNode>(std::make_unique<TrackingVolume>(
0089 Transform3::Identity(), cylBounds, "child2")));
0090
0091 BOOST_CHECK_THROW(root.construct({}, gctx, *logger), std::logic_error);
0092 }
0093
0094 class DummyNode : public BlueprintNode {
0095 public:
0096 explicit DummyNode(const std::string& name) : m_name(name) {}
0097
0098 const std::string& name() const override { return m_name; }
0099
0100 Volume& build(const BlueprintOptions& ,
0101 const GeometryContext& ,
0102 const Acts::Logger& ) override {
0103 throw std::logic_error("Not implemented");
0104 }
0105
0106 PortalShellBase& connect(const BlueprintOptions& ,
0107 const GeometryContext& ,
0108 const Logger& ) override {
0109 throw std::logic_error("Not implemented");
0110 }
0111
0112 void finalize(const BlueprintOptions& ,
0113 const GeometryContext& , TrackingVolume& ,
0114 const Logger& ) override {
0115 throw std::logic_error("Not implemented");
0116 }
0117
0118 private:
0119 std::string m_name;
0120 };
0121
0122 BOOST_AUTO_TEST_CASE(RootCannotBeChild) {
0123 auto node = std::make_shared<DummyNode>("node");
0124 Blueprint::Config cfg;
0125 auto root = std::make_shared<Blueprint>(cfg);
0126
0127 BOOST_CHECK_THROW(node->addChild(root), std::invalid_argument);
0128 }
0129
0130 BOOST_AUTO_TEST_CASE(AddChildInvalid) {
0131 auto node = std::make_shared<DummyNode>("node");
0132
0133
0134 BOOST_CHECK_THROW(node->addChild(node), std::invalid_argument);
0135
0136
0137 BOOST_CHECK_THROW(node->addChild(nullptr), std::invalid_argument);
0138
0139 auto nodeB = std::make_shared<DummyNode>("nodeB");
0140 auto nodeC = std::make_shared<DummyNode>("nodeC");
0141
0142 node->addChild(nodeB);
0143 nodeB->addChild(nodeC);
0144 BOOST_CHECK_THROW(nodeC->addChild(node), std::invalid_argument);
0145
0146
0147 BOOST_CHECK_THROW(node->addChild(nodeC), std::invalid_argument);
0148 }
0149
0150 BOOST_AUTO_TEST_CASE(Depth) {
0151 auto node1 = std::make_shared<DummyNode>("node1");
0152 auto node2 = std::make_shared<DummyNode>("node2");
0153 auto node3 = std::make_shared<DummyNode>("node3");
0154
0155 BOOST_CHECK_EQUAL(node1->depth(), 0);
0156 BOOST_CHECK_EQUAL(node2->depth(), 0);
0157 BOOST_CHECK_EQUAL(node3->depth(), 0);
0158
0159 node2->addChild(node3);
0160 BOOST_CHECK_EQUAL(node2->depth(), 0);
0161 BOOST_CHECK_EQUAL(node3->depth(), 1);
0162
0163 node1->addChild(node2);
0164 BOOST_CHECK_EQUAL(node1->depth(), 0);
0165 BOOST_CHECK_EQUAL(node2->depth(), 1);
0166 BOOST_CHECK_EQUAL(node3->depth(), 2);
0167 }
0168
0169 BOOST_AUTO_TEST_CASE(Static) {
0170 Blueprint::Config cfg;
0171 cfg.envelope[AxisDirection::AxisZ] = {20_mm, 20_mm};
0172 cfg.envelope[AxisDirection::AxisR] = {1_mm, 2_mm};
0173 Blueprint root{cfg};
0174
0175 double hlZ = 30_mm;
0176 auto cylBounds = std::make_shared<CylinderVolumeBounds>(10_mm, 20_mm, hlZ);
0177 auto cyl = std::make_unique<TrackingVolume>(Transform3::Identity(), cylBounds,
0178 "child");
0179
0180 root.addStaticVolume(std::move(cyl));
0181
0182 BOOST_CHECK_EQUAL(root.children().size(), 1);
0183
0184 auto tGeometry = root.construct({}, gctx, *logger);
0185
0186 BOOST_REQUIRE(tGeometry);
0187
0188 BOOST_CHECK_EQUAL(tGeometry->highestTrackingVolume()->volumes().size(), 1);
0189
0190 BOOST_CHECK_EQUAL(countVolumes(*tGeometry), 2);
0191
0192 auto lookup = nameLookup(*tGeometry);
0193 auto actCyl =
0194 dynamic_cast<const CylinderVolumeBounds&>(lookup("child").volumeBounds());
0195
0196 BOOST_CHECK_EQUAL(actCyl.get(CylinderVolumeBounds::eMinR), 10_mm);
0197 BOOST_CHECK_EQUAL(actCyl.get(CylinderVolumeBounds::eMaxR), 20_mm);
0198 BOOST_CHECK_EQUAL(actCyl.get(CylinderVolumeBounds::eHalfLengthZ), hlZ);
0199
0200 auto worldCyl =
0201 dynamic_cast<const CylinderVolumeBounds&>(lookup("World").volumeBounds());
0202 BOOST_CHECK_EQUAL(worldCyl.get(CylinderVolumeBounds::eMinR), 9_mm);
0203 BOOST_CHECK_EQUAL(worldCyl.get(CylinderVolumeBounds::eMaxR), 22_mm);
0204 BOOST_CHECK_EQUAL(worldCyl.get(CylinderVolumeBounds::eHalfLengthZ),
0205 hlZ + 20_mm);
0206
0207 BOOST_CHECK_EQUAL(lookup("World").portals().size(), 8);
0208 }
0209
0210 BOOST_AUTO_TEST_CASE(CylinderContainer) {
0211 Blueprint::Config cfg;
0212 cfg.envelope[AxisDirection::AxisZ] = {20_mm, 20_mm};
0213 cfg.envelope[AxisDirection::AxisR] = {2_mm, 20_mm};
0214 auto root = std::make_unique<Blueprint>(cfg);
0215
0216 auto& cyl = root->addCylinderContainer("Container", AxisDirection::AxisZ);
0217 cyl.setAttachmentStrategy(CylinderVolumeStack::AttachmentStrategy::Gap);
0218
0219 double z0 = -200_mm;
0220 double hlZ = 30_mm;
0221 auto cylBounds = std::make_shared<CylinderVolumeBounds>(10_mm, 20_mm, hlZ);
0222 for (std::size_t i = 0; i < 3; i++) {
0223 auto childCyl = std::make_unique<TrackingVolume>(
0224 Transform3::Identity() *
0225 Translation3{Vector3{0, 0, z0 + i * 2 * hlZ * 1.2}},
0226 cylBounds, "child" + std::to_string(i));
0227 cyl.addStaticVolume(std::move(childCyl));
0228 }
0229
0230 auto tGeometry = root->construct({}, gctx, *logger);
0231
0232
0233 BOOST_CHECK_EQUAL(countVolumes(*tGeometry), 6);
0234
0235 auto lookup = nameLookup(*tGeometry);
0236 auto worldCyl =
0237 dynamic_cast<const CylinderVolumeBounds&>(lookup("World").volumeBounds());
0238 BOOST_CHECK_EQUAL(worldCyl.get(CylinderVolumeBounds::eMinR), 8_mm);
0239 BOOST_CHECK_EQUAL(worldCyl.get(CylinderVolumeBounds::eMaxR), 40_mm);
0240 BOOST_CHECK_EQUAL(worldCyl.get(CylinderVolumeBounds::eHalfLengthZ), 122_mm);
0241
0242 BOOST_CHECK_EQUAL(lookup("World").portals().size(), 8);
0243
0244 for (std::size_t i = 0; i < 3; i++) {
0245 auto actCyl = dynamic_cast<const CylinderVolumeBounds&>(
0246 lookup("child" + std::to_string(i)).volumeBounds());
0247 BOOST_CHECK_EQUAL(actCyl.get(CylinderVolumeBounds::eMinR), 10_mm);
0248 BOOST_CHECK_EQUAL(actCyl.get(CylinderVolumeBounds::eMaxR), 20_mm);
0249 BOOST_CHECK_EQUAL(actCyl.get(CylinderVolumeBounds::eHalfLengthZ), hlZ);
0250 }
0251
0252 for (std::size_t i = 0; i < 2; i++) {
0253 auto gapCyl = dynamic_cast<const CylinderVolumeBounds&>(
0254 lookup("Container::Gap" + std::to_string(i + 1)).volumeBounds());
0255 BOOST_CHECK_EQUAL(gapCyl.get(CylinderVolumeBounds::eMinR), 10_mm);
0256 BOOST_CHECK_EQUAL(gapCyl.get(CylinderVolumeBounds::eMaxR), 20_mm);
0257 BOOST_CHECK_EQUAL(gapCyl.get(CylinderVolumeBounds::eHalfLengthZ), 6_mm);
0258 }
0259 }
0260
0261 BOOST_AUTO_TEST_CASE(Confined) {
0262 Transform3 base{Transform3::Identity()};
0263
0264 Blueprint::Config cfg;
0265 cfg.envelope[AxisDirection::AxisZ] = {20_mm, 20_mm};
0266 cfg.envelope[AxisDirection::AxisR] = {2_mm, 20_mm};
0267 auto root = std::make_unique<Blueprint>(cfg);
0268
0269 root->addStaticVolume(
0270 base, std::make_shared<CylinderVolumeBounds>(50_mm, 400_mm, 1000_mm),
0271 "PixelWrapper", [&](auto& wrap) {
0272 double rMin = 100_mm;
0273 double rMax = 350_mm;
0274 double hlZ = 100_mm;
0275
0276 wrap.addStaticVolume(
0277 base * Translation3{Vector3{0, 0, -600_mm}},
0278 std::make_shared<CylinderVolumeBounds>(rMin, rMax, hlZ),
0279 "PixelNeg1");
0280
0281 wrap.addStaticVolume(
0282 base * Translation3{Vector3{0, 0, -200_mm}},
0283 std::make_shared<CylinderVolumeBounds>(rMin, rMax, hlZ),
0284 "PixelNeg2");
0285
0286 wrap.addStaticVolume(
0287 base * Translation3{Vector3{0, 0, 200_mm}},
0288 std::make_shared<CylinderVolumeBounds>(rMin, rMax, hlZ),
0289 "PixelPos1");
0290
0291 wrap.addStaticVolume(
0292 base * Translation3{Vector3{0, 0, 600_mm}},
0293 std::make_shared<CylinderVolumeBounds>(rMin, rMax, hlZ),
0294 "PixelPos2");
0295 });
0296
0297 auto trackingGeometry = root->construct({}, gctx, *logger);
0298
0299
0300 auto lookup = nameLookup(*trackingGeometry);
0301 auto worldCyl =
0302 dynamic_cast<const CylinderVolumeBounds&>(lookup("World").volumeBounds());
0303 BOOST_CHECK_EQUAL(worldCyl.get(CylinderVolumeBounds::eMinR), 48_mm);
0304 BOOST_CHECK_EQUAL(worldCyl.get(CylinderVolumeBounds::eMaxR), 420_mm);
0305 BOOST_CHECK_EQUAL(worldCyl.get(CylinderVolumeBounds::eHalfLengthZ), 1020_mm);
0306
0307
0308 BOOST_CHECK_EQUAL(lookup("World").portals().size(), 8);
0309 BOOST_CHECK_EQUAL(lookup("World").volumes().size(), 1);
0310
0311 auto wrapperCyl = dynamic_cast<const CylinderVolumeBounds&>(
0312 lookup("PixelWrapper").volumeBounds());
0313 BOOST_CHECK_EQUAL(wrapperCyl.get(CylinderVolumeBounds::eMinR), 50_mm);
0314 BOOST_CHECK_EQUAL(wrapperCyl.get(CylinderVolumeBounds::eMaxR), 400_mm);
0315 BOOST_CHECK_EQUAL(wrapperCyl.get(CylinderVolumeBounds::eHalfLengthZ),
0316 1000_mm);
0317 BOOST_CHECK_EQUAL(lookup("PixelWrapper").portals().size(), 4 + 4 * 4);
0318 BOOST_CHECK_EQUAL(lookup("PixelWrapper").volumes().size(), 4);
0319
0320 for (const auto& name :
0321 {"PixelNeg1", "PixelNeg2", "PixelPos1", "PixelPos2"}) {
0322 auto actCyl =
0323 dynamic_cast<const CylinderVolumeBounds&>(lookup(name).volumeBounds());
0324 BOOST_CHECK_EQUAL(actCyl.get(CylinderVolumeBounds::eMinR), 100_mm);
0325 BOOST_CHECK_EQUAL(actCyl.get(CylinderVolumeBounds::eMaxR), 350_mm);
0326 BOOST_CHECK_EQUAL(actCyl.get(CylinderVolumeBounds::eHalfLengthZ), 100_mm);
0327 BOOST_CHECK_EQUAL(lookup(name).portals().size(), 4);
0328 }
0329 }
0330
0331 BOOST_AUTO_TEST_CASE(DiscLayer) {
0332 double yrot = 45_degree;
0333 Transform3 base = Transform3::Identity() * AngleAxis3{yrot, Vector3::UnitY()};
0334
0335 std::vector<std::shared_ptr<Surface>> surfaces;
0336 std::vector<std::unique_ptr<DetectorElementBase>> elements;
0337 double r = 300_mm;
0338 std::size_t nSensors = 8;
0339 double thickness = 2.5_mm;
0340 auto recBounds = std::make_shared<RectangleBounds>(40_mm, 60_mm);
0341
0342 double deltaPhi = 2 * std::numbers::pi / nSensors;
0343 for (std::size_t i = 0; i < nSensors; i++) {
0344
0345
0346 Transform3 trf = base * AngleAxis3{deltaPhi * i, Vector3::UnitZ()} *
0347 Translation3(Vector3::UnitX() * r);
0348
0349 if (i % 2 == 0) {
0350 trf = trf * Translation3{Vector3::UnitZ() * 5_mm};
0351 }
0352
0353 auto& element = elements.emplace_back(
0354 std::make_unique<DetectorElementStub>(trf, recBounds, thickness));
0355
0356 element->surface().assignDetectorElement(*element);
0357
0358 surfaces.push_back(element->surface().getSharedPtr());
0359 }
0360
0361 Blueprint root{{.envelope = ExtentEnvelope{{
0362 .z = {2_mm, 2_mm},
0363 .r = {3_mm, 5_mm},
0364 }}}};
0365
0366 root.addLayer("Layer0", [&](auto& layer) {
0367 layer.setSurfaces(surfaces)
0368 .setLayerType(LayerBlueprintNode::LayerType::Disc)
0369 .setEnvelope(ExtentEnvelope{{
0370 .z = {0.1_mm, 0.1_mm},
0371 .r = {1_mm, 1_mm},
0372 }})
0373 .setTransform(base);
0374 });
0375
0376 auto trackingGeometry = root.construct({}, gctx, *logger);
0377
0378 std::size_t nSurfaces = 0;
0379
0380 trackingGeometry->visitSurfaces([&](const Surface* surface) {
0381 if (surface->associatedDetectorElement() != nullptr) {
0382 nSurfaces++;
0383 }
0384 });
0385
0386 BOOST_CHECK_EQUAL(nSurfaces, surfaces.size());
0387 BOOST_CHECK_EQUAL(countVolumes(*trackingGeometry), 2);
0388 auto lookup = nameLookup(*trackingGeometry);
0389 auto layerCyl = dynamic_cast<const CylinderVolumeBounds&>(
0390 lookup("Layer0").volumeBounds());
0391 BOOST_CHECK_CLOSE(layerCyl.get(CylinderVolumeBounds::eMinR), 258.9999999_mm,
0392 1e-6);
0393 BOOST_CHECK_CLOSE(layerCyl.get(CylinderVolumeBounds::eMaxR), 346.25353003_mm,
0394 1e-6);
0395 BOOST_CHECK_CLOSE(layerCyl.get(CylinderVolumeBounds::eHalfLengthZ), 3.85_mm,
0396 1e-6);
0397 }
0398
0399 BOOST_AUTO_TEST_CASE(CylinderLayer) {
0400 double yrot = 0_degree;
0401 Transform3 base = Transform3::Identity() * AngleAxis3{yrot, Vector3::UnitY()};
0402
0403 std::vector<std::shared_ptr<Surface>> surfaces;
0404 std::vector<std::unique_ptr<DetectorElementBase>> elements;
0405
0406 double r = 300_mm;
0407 std::size_t nStaves = 10;
0408 int nSensorsPerStave = 8;
0409 double thickness = 0;
0410 double hlPhi = 40_mm;
0411 double hlZ = 60_mm;
0412 auto recBounds = std::make_shared<RectangleBounds>(hlPhi, hlZ);
0413
0414 double deltaPhi = 2 * std::numbers::pi / nStaves;
0415
0416 for (std::size_t istave = 0; istave < nStaves; istave++) {
0417 for (int isensor = -nSensorsPerStave; isensor <= nSensorsPerStave;
0418 isensor++) {
0419 double z = isensor * (2 * hlZ + 5_mm);
0420
0421 Transform3 trf = base * Translation3(Vector3::UnitZ() * z) *
0422 AngleAxis3{deltaPhi * istave, Vector3::UnitZ()} *
0423 Translation3(Vector3::UnitX() * r) *
0424 AngleAxis3{10_degree, Vector3::UnitZ()} *
0425 AngleAxis3{90_degree, Vector3::UnitY()} *
0426 AngleAxis3{90_degree, Vector3::UnitZ()};
0427 auto& element = elements.emplace_back(
0428 std::make_unique<DetectorElementStub>(trf, recBounds, thickness));
0429 element->surface().assignDetectorElement(*element);
0430 surfaces.push_back(element->surface().getSharedPtr());
0431 }
0432 }
0433
0434 Blueprint root{{.envelope = ExtentEnvelope{{
0435 .z = {2_mm, 2_mm},
0436 .r = {3_mm, 5_mm},
0437 }}}};
0438
0439 root.addLayer("Layer0", [&](auto& layer) {
0440 layer.setSurfaces(surfaces)
0441 .setLayerType(LayerBlueprintNode::LayerType::Cylinder)
0442 .setEnvelope(ExtentEnvelope{{
0443 .z = {10_mm, 10_mm},
0444 .r = {20_mm, 10_mm},
0445 }})
0446 .setTransform(base);
0447 });
0448
0449 auto trackingGeometry = root.construct({}, gctx, *logger);
0450
0451 std::size_t nSurfaces = 0;
0452
0453 trackingGeometry->visitSurfaces([&](const Surface* surface) {
0454 if (surface->associatedDetectorElement() != nullptr) {
0455 nSurfaces++;
0456 }
0457 });
0458
0459 BOOST_CHECK_EQUAL(nSurfaces, surfaces.size());
0460 BOOST_CHECK_EQUAL(countVolumes(*trackingGeometry), 2);
0461 auto lookup = nameLookup(*trackingGeometry);
0462 auto layerCyl = dynamic_cast<const CylinderVolumeBounds&>(
0463 lookup("Layer0").volumeBounds());
0464 BOOST_CHECK_EQUAL(lookup("Layer0").portals().size(), 4);
0465 BOOST_CHECK_CLOSE(layerCyl.get(CylinderVolumeBounds::eMinR), 275.6897761_mm,
0466 1e-6);
0467 BOOST_CHECK_CLOSE(layerCyl.get(CylinderVolumeBounds::eMaxR), 319.4633358_mm,
0468 1e-6);
0469 BOOST_CHECK_CLOSE(layerCyl.get(CylinderVolumeBounds::eHalfLengthZ), 1070_mm,
0470 1e-6);
0471 }
0472
0473 BOOST_AUTO_TEST_CASE(Material) {
0474 Blueprint::Config cfg;
0475 cfg.envelope[AxisDirection::AxisZ] = {20_mm, 20_mm};
0476 cfg.envelope[AxisDirection::AxisR] = {1_mm, 2_mm};
0477 Blueprint root{cfg};
0478
0479 double hlZ = 30_mm;
0480 auto cylBounds = std::make_shared<CylinderVolumeBounds>(10_mm, 20_mm, hlZ);
0481 auto cyl = std::make_unique<TrackingVolume>(Transform3::Identity(), cylBounds,
0482 "child");
0483
0484 using enum AxisDirection;
0485 using enum CylinderVolumeBounds::Face;
0486 using enum AxisBoundaryType;
0487
0488 root.addMaterial("Material", [&](auto& mat) {
0489
0490 mat.setBinning(std::vector{
0491 std::tuple{NegativeDisc, Experimental::ProtoBinning{AxisR, Bound, 5},
0492 Experimental::ProtoBinning{AxisPhi, Bound, 10}},
0493 std::tuple{PositiveDisc, Experimental::ProtoBinning{AxisR, Bound, 15},
0494 Experimental::ProtoBinning{AxisPhi, Bound, 20}},
0495 });
0496
0497 mat.addStaticVolume(std::move(cyl));
0498 });
0499
0500 auto trackingGeometry = root.construct({}, gctx, *logger);
0501
0502 BOOST_CHECK_EQUAL(countVolumes(*trackingGeometry), 2);
0503 auto lookup = nameLookup(*trackingGeometry);
0504 auto& child = lookup("child");
0505
0506 const auto* negDisc = child.portals().at(0).surface().surfaceMaterial();
0507 const auto* posDisc = child.portals().at(1).surface().surfaceMaterial();
0508 BOOST_CHECK_NE(negDisc, nullptr);
0509 BOOST_CHECK_NE(posDisc, nullptr);
0510
0511 const auto& negDiscMat =
0512 dynamic_cast<const ProtoGridSurfaceMaterial&>(*negDisc);
0513 const auto& posDiscMat =
0514 dynamic_cast<const ProtoGridSurfaceMaterial&>(*posDisc);
0515
0516 BOOST_CHECK_EQUAL(negDiscMat.binning().binning.at(0).bins(), 5);
0517 BOOST_CHECK_EQUAL(negDiscMat.binning().binning.at(1).bins(), 10);
0518 BOOST_CHECK_EQUAL(posDiscMat.binning().binning.at(0).bins(), 15);
0519 BOOST_CHECK_EQUAL(posDiscMat.binning().binning.at(1).bins(), 20);
0520
0521 for (std::size_t i = 2; i < child.portals().size(); i++) {
0522 BOOST_CHECK_EQUAL(child.portals().at(i).surface().surfaceMaterial(),
0523 nullptr);
0524 }
0525 }
0526
0527 BOOST_AUTO_TEST_SUITE_END();
0528
0529 BOOST_AUTO_TEST_SUITE_END();
0530
0531 }