diff --git a/src/celeritas/ext/GeantSetup.cc b/src/celeritas/ext/GeantSetup.cc index 295bfda76b..050d17213f 100644 --- a/src/celeritas/ext/GeantSetup.cc +++ b/src/celeritas/ext/GeantSetup.cc @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #if G4VERSION_NUMBER >= 1070 @@ -30,6 +31,7 @@ #include "geocel/GeantUtils.hh" #include "geocel/ScopedGeantExceptionHandler.hh" #include "geocel/ScopedGeantLogger.hh" +#include "celeritas/g4/DetectorConstruction.hh" #include "EmPhysicsList.hh" @@ -37,22 +39,18 @@ namespace celeritas { namespace { + //---------------------------------------------------------------------------// -/*! - * Load the detector geometry from a GDML input file. - */ -class DetectorConstruction : public G4VUserDetectorConstruction +//! Placeholder SD class for generating model data from GDML +class GdmlSensitiveDetector final : public G4VSensitiveDetector { public: - explicit DetectorConstruction(G4VPhysicalVolume* world) : world_{world} + GdmlSensitiveDetector(std::string const& name) : G4VSensitiveDetector{name} { - CELER_ENSURE(world_); } - G4VPhysicalVolume* Construct() override { return world_; } - - private: - G4VPhysicalVolume* world_; + void Initialize(G4HCofThisEvent*) final {} + bool ProcessHits(G4Step*, G4TouchableHistory*) final { return false; } }; //---------------------------------------------------------------------------// @@ -102,17 +100,21 @@ GeantSetup::GeantSetup(std::string const& gdml_filename, Options options) ScopedGeantLogger scoped_logger(celeritas::world_logger()); ScopedGeantExceptionHandler scoped_exceptions; - G4VPhysicalVolume* world{nullptr}; + DetectorConstruction const* p_detector = nullptr; { CELER_LOG(status) << "Initializing Geant4 geometry and physics list"; // Load GDML and reference the world pointer // TODO: pass GdmlLoader options through SetupOptions - world = load_gdml(gdml_filename); - CELER_ASSERT(world); // Construct the geometry - auto detector = std::make_unique(world); + // auto detector = std::make_unique(world); + auto build_sd_functor = [](std::string const& name) { + return std::make_unique(name); + }; + auto detector = std::make_unique( + gdml_filename, build_sd_functor); + p_detector = detector.get(); run_manager_->SetUserInitialization(detector.release()); // Construct the physics @@ -131,7 +133,8 @@ GeantSetup::GeantSetup(std::string const& gdml_filename, Options options) { // Create non-owning Geant4 geo wrapper and save as tracking geometry - geo_ = std::make_shared(world, Ownership::reference); + geo_ = std::make_shared(p_detector->world(), + Ownership::reference); celeritas::global_geant_geo(geo_); } diff --git a/src/celeritas/global/CoreParams.cc b/src/celeritas/global/CoreParams.cc index 19a91ee519..09e1362627 100644 --- a/src/celeritas/global/CoreParams.cc +++ b/src/celeritas/global/CoreParams.cc @@ -54,6 +54,7 @@ #include "celeritas/track/SimParams.hh" // IWYU pragma: keep #include "celeritas/track/SortTracksAction.hh" #include "celeritas/track/TrackInitParams.hh" // IWYU pragma: keep +#include "celeritas/user/SDParams.hh" #include "ActionInterface.hh" @@ -91,6 +92,7 @@ build_params_refs(CoreParams::Input const& p, CoreScalars const& scalars) ref.cutoffs = get_ref(*p.cutoff); ref.physics = get_ref(*p.physics); ref.rng = get_ref(*p.rng); + ref.detector = get_ref(*p.detector); ref.sim = get_ref(*p.sim); ref.surface = get_ref(*p.surface); ref.init = get_ref(*p.init); diff --git a/src/celeritas/global/CoreParams.hh b/src/celeritas/global/CoreParams.hh index af20e438de..712874e053 100644 --- a/src/celeritas/global/CoreParams.hh +++ b/src/celeritas/global/CoreParams.hh @@ -28,6 +28,7 @@ class MpiCommunicator; class OutputRegistry; class ParticleParams; class PhysicsParams; +class SDParams; class SimParams; class SurfaceParams; class TrackInitParams; @@ -56,6 +57,7 @@ class CoreParams final : public ParamsDataInterface using SPConstCutoff = std::shared_ptr; using SPConstPhysics = std::shared_ptr; using SPConstRng = std::shared_ptr; + using SPConstSensDet = std::shared_ptr; using SPConstSim = std::shared_ptr; using SPConstSurface = std::shared_ptr; using SPConstTrackInit = std::shared_ptr; @@ -83,6 +85,7 @@ class CoreParams final : public ParamsDataInterface SPConstCutoff cutoff; SPConstPhysics physics; SPConstRng rng; + SPConstSensDet detector; SPConstSim sim; SPConstSurface surface; SPConstTrackInit init; @@ -125,6 +128,7 @@ class CoreParams final : public ParamsDataInterface SPConstCutoff const& cutoff() const { return input_.cutoff; } SPConstPhysics const& physics() const { return input_.physics; } SPConstRng const& rng() const { return input_.rng; } + SPConstSensDet const& detector() const { return input_.detector; } SPConstSim const& sim() const { return input_.sim; } SPConstSurface const& surface() const { return input_.surface; } SPConstTrackInit const& init() const { return input_.init; } diff --git a/src/celeritas/global/CoreTrackData.hh b/src/celeritas/global/CoreTrackData.hh index e2e5543737..9aa94d3c22 100644 --- a/src/celeritas/global/CoreTrackData.hh +++ b/src/celeritas/global/CoreTrackData.hh @@ -21,6 +21,7 @@ #include "celeritas/phys/PhysicsData.hh" #include "celeritas/track/SimData.hh" #include "celeritas/track/TrackInitData.hh" +#include "celeritas/user/SDData.hh" #include "CoreTrackDataFwd.hh" @@ -72,6 +73,7 @@ struct CoreParamsData CutoffParamsData cutoffs; PhysicsParamsData physics; RngParamsData rng; + SDParamsData detector; SimParamsData sim; SurfaceParamsData surface; TrackInitParamsData init; @@ -98,6 +100,7 @@ struct CoreParamsData cutoffs = other.cutoffs; physics = other.physics; rng = other.rng; + detector = other.detector; sim = other.sim; surface = other.surface; init = other.init; diff --git a/src/celeritas/optical/CoreParams.cc b/src/celeritas/optical/CoreParams.cc index f115ee8701..2f671cd6d4 100644 --- a/src/celeritas/optical/CoreParams.cc +++ b/src/celeritas/optical/CoreParams.cc @@ -52,7 +52,7 @@ build_params_refs(CoreParams::Input const& p, CoreScalars const& scalars) ref.surface = get_ref(*p.surface); ref.surface_physics = get_ref(*p.surface_physics); ref.rng = get_ref(*p.rng); - // TODO: Get detectors ref + ref.detectors = get_ref(*p.detectors); if (p.cherenkov) { ref.cherenkov = get_ref(*p.cherenkov); @@ -119,17 +119,11 @@ CoreParams::CoreParams(Input&& input) : input_(std::move(input)) CP_VALIDATE_INPUT(action_reg); CP_VALIDATE_INPUT(gen_reg); CP_VALIDATE_INPUT(max_streams); + CP_VALIDATE_INPUT(detectors); #undef CP_VALIDATE_INPUT CELER_EXPECT(input_); - // TODO: provide detectors in input, passing from core params - detectors_ = input_.detectors; - if (!detectors_) - { - detectors_ = std::make_shared(); - } - ScopedMem record_mem("optical::CoreParams.construct"); // Construct always-on actions and save their IDs diff --git a/src/celeritas/optical/CoreParams.hh b/src/celeritas/optical/CoreParams.hh index 63e14d612e..aa34bcfce1 100644 --- a/src/celeritas/optical/CoreParams.hh +++ b/src/celeritas/optical/CoreParams.hh @@ -112,7 +112,7 @@ class CoreParams final : public ParamsDataInterface } SPActionRegistry const& action_reg() const { return input_.action_reg; } SPGeneratorRegistry const& gen_reg() const { return input_.gen_reg; } - SPConstDetectors const& detectors() const { return detectors_; } + SPConstDetectors const& detectors() const { return input_.detectors; } SPConstCherenkov const& cherenkov() const { return input_.cherenkov; } SPConstScintillation const& scintillation() const { @@ -137,8 +137,6 @@ class CoreParams final : public ParamsDataInterface // Copy of DeviceRef in device memory DeviceVector device_ref_vec_; - - SPConstDetectors detectors_; }; //---------------------------------------------------------------------------// diff --git a/src/celeritas/optical/CoreTrackData.hh b/src/celeritas/optical/CoreTrackData.hh index fb541f3b46..c2886cfa5d 100644 --- a/src/celeritas/optical/CoreTrackData.hh +++ b/src/celeritas/optical/CoreTrackData.hh @@ -12,6 +12,7 @@ #include "geocel/SurfaceData.hh" #include "celeritas/Types.hh" #include "celeritas/geo/GeoData.hh" +#include "celeritas/user/SDData.hh" #include "CoreTrackDataFwd.hh" #include "MaterialData.hh" @@ -55,6 +56,7 @@ struct CoreParamsData RngParamsData rng; SurfaceParamsData surface; SurfacePhysicsParamsData surface_physics; + SDParamsData detectors; CherenkovData cherenkov; ScintillationData scintillation; diff --git a/src/celeritas/optical/CoreTrackView.hh b/src/celeritas/optical/CoreTrackView.hh index 57ffa62d9b..6f0ff08555 100644 --- a/src/celeritas/optical/CoreTrackView.hh +++ b/src/celeritas/optical/CoreTrackView.hh @@ -14,6 +14,7 @@ #include "MaterialView.hh" #include "ParticleTrackView.hh" #include "PhysicsTrackView.hh" +#include "SensitiveDetectorView.hh" #include "SimTrackView.hh" #include "TrackInitializer.hh" #include "surface/SurfacePhysicsTrackView.hh" @@ -78,6 +79,9 @@ class CoreTrackView // Return a surface physics view inline CELER_FUNCTION SurfacePhysicsTrackView surface_physics() const; + // Return a sensitive detector view + inline CELER_FUNCTION SensitiveDetectorView sensitive_detectors() const; + // Return an RNG engine inline CELER_FUNCTION RngEngine rng() const; @@ -246,6 +250,16 @@ CELER_FUNCTION auto CoreTrackView::surface_physics() const this->track_slot_id()}; } +//---------------------------------------------------------------------------// +/*! + * Return a sensitive detector view. + */ +CELER_FUNCTION auto CoreTrackView::sensitive_detectors() const + -> SensitiveDetectorView +{ + return SensitiveDetectorView{params_.detectors}; +} + //---------------------------------------------------------------------------// /*! * Return the RNG engine. diff --git a/src/celeritas/optical/SensitiveDetectorView.hh b/src/celeritas/optical/SensitiveDetectorView.hh new file mode 100644 index 0000000000..f20beb6e09 --- /dev/null +++ b/src/celeritas/optical/SensitiveDetectorView.hh @@ -0,0 +1,44 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/SensitiveDetectorView.hh +//---------------------------------------------------------------------------// +#pragma once + +#include "geocel/Types.hh" +#include "celeritas/Quantities.hh" +#include "celeritas/user/SDData.hh" + +namespace celeritas +{ +namespace optical +{ + +class SensitiveDetectorView +{ + using SDParamsRef = NativeCRef; + + public: + inline CELER_FUNCTION SensitiveDetectorView(SDParamsRef const& params); + + inline auto CELER_FUNCTION detector_id(ImplVolumeId iv_id); + + private: + SDParamsRef const& params_; +}; + +CELER_FUNCTION +SensitiveDetectorView::SensitiveDetectorView(SDParamsRef const& params) + : params_(params) +{ + CELER_EXPECT(params_); +} + +CELER_FUNCTION auto SensitiveDetectorView::detector_id(ImplVolumeId iv_id) +{ + return params_.detector[iv_id]; +} + +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/detail/PostBoundaryExecutor.hh b/src/celeritas/optical/surface/detail/PostBoundaryExecutor.hh index 0c92919bf2..104d0e2fcf 100644 --- a/src/celeritas/optical/surface/detail/PostBoundaryExecutor.hh +++ b/src/celeritas/optical/surface/detail/PostBoundaryExecutor.hh @@ -38,13 +38,28 @@ struct PostBoundaryExecutor */ CELER_FUNCTION void PostBoundaryExecutor::operator()(CoreTrackView& track) const { + auto geo = track.geometry(); + auto det_params = track.sensitive_detectors(); + ImplVolumeId iv_id = geo.impl_volume_id(); + + DetectorId det_id = det_params.detector_id(iv_id); + if (det_id) + { + auto energy = track.particle().energy(); + // TODO print energy when killing at SD + std::cout << "Detector hit in volume " << iv_id.get() + << " on detector " << det_id.get() << " with energy " + << energy.value() << std::endl; + track.sim().status(TrackStatus::killed); + } + auto traverse = track.surface_physics().traversal(); CELER_EXPECT(traverse.is_exiting()); if (traverse.in_pre_volume()) { // Re-entrant into the pre-volume - auto geo = track.geometry(); + // auto geo = track.geometry(); geo.cross_boundary(); if (CELER_UNLIKELY(geo.failed())) { diff --git a/src/celeritas/setup/Model.cc b/src/celeritas/setup/Model.cc index a8f41e200c..827ab7b8c7 100644 --- a/src/celeritas/setup/Model.cc +++ b/src/celeritas/setup/Model.cc @@ -14,6 +14,7 @@ #include "geocel/VolumeParams.hh" #include "geocel/inp/Model.hh" #include "celeritas/geo/CoreGeoParams.hh" // IWYU pragma: keep +#include "celeritas/user/SDParams.hh" namespace celeritas { @@ -118,6 +119,8 @@ ModelLoaded model(inp::Model const& m) result.surface = std::make_shared(m.surfaces, *result.volume); + result.detector = std::make_shared(*result.geometry, m.detectors); + return result; } diff --git a/src/celeritas/setup/Model.hh b/src/celeritas/setup/Model.hh index edd816324d..7ccd01bd68 100644 --- a/src/celeritas/setup/Model.hh +++ b/src/celeritas/setup/Model.hh @@ -20,6 +20,7 @@ struct Model; class SurfaceParams; class VolumeParams; +class SDParams; namespace setup { @@ -30,6 +31,7 @@ struct ModelLoaded std::shared_ptr geometry; std::shared_ptr surface; std::shared_ptr volume; + std::shared_ptr detector; }; //---------------------------------------------------------------------------// diff --git a/src/celeritas/setup/Problem.cc b/src/celeritas/setup/Problem.cc index e5b76d10c8..8d3061ac05 100644 --- a/src/celeritas/setup/Problem.cc +++ b/src/celeritas/setup/Problem.cc @@ -313,6 +313,7 @@ auto build_optical_params(inp::OpticalPhysics const& optical, params.action_reg = std::make_shared(); params.gen_reg = std::make_shared(); params.max_streams = core.max_streams(); + params.detectors = core.detector(); { // Construct optical physics models optical::PhysicsParams::Input pp_inp; @@ -459,6 +460,7 @@ ProblemLoaded problem(inp::Problem const& p, ImportData const& imported) } params.surface = std::make_shared(); } + params.detector = std::move(loaded_model.detector); } // Load materials diff --git a/src/celeritas/user/SDParams.cc b/src/celeritas/user/SDParams.cc index 176e7d6fe2..d6c30707a8 100644 --- a/src/celeritas/user/SDParams.cc +++ b/src/celeritas/user/SDParams.cc @@ -9,8 +9,12 @@ #include #include "corecel/data/CollectionBuilder.hh" -#include "geocel/GeoParamsInterface.hh" +// #include "geocel/GeantGeoParams.hh" #include "geocel/VolumeCollectionBuilder.hh" +// #include "geocel/vg/VecgeomParams.hh" +// #include "orange/OrangeParams.hh" +#include "corecel/io/Logger.hh" +#include "celeritas/geo/CoreGeoParams.hh" namespace celeritas { @@ -18,25 +22,37 @@ namespace celeritas /*! * Construct from list of volume labels. */ -SDParams::SDParams(GeoParamsInterface const& geo, VecVolId&& volume_ids) - : volume_ids_{std::move(volume_ids)} +SDParams::SDParams(CoreGeoParams const& geo, inp::Detectors detectors) + : detectors_{std::move(detectors)} { - CELER_EXPECT(!volume_ids_.empty()); + if (!detectors_) + { + CELER_LOG(warning) << "Empty detectors list passed to SDParams"; + } // Map labels to volume IDs auto const num_impl_volumes = geo.impl_volumes().size(); - CELER_VALIDATE(std::all_of(volume_ids_.begin(), - volume_ids_.end(), - [num_impl_volumes](VolumeId id) { - return id < num_impl_volumes; - }), - << "invalid volume IDs given to SDParams"); + for (auto& detector : detectors_.detectors) + { + CELER_VALIDATE(std::all_of(detector.volumes.begin(), + detector.volumes.end(), + [num_impl_volumes](VolumeId id) { + return id < num_impl_volumes; + }), + << "invalid volume IDs given to SDParams"); + } std::unordered_map detector_map; - for (auto didx : range(volume_ids_.size())) + for (size_type det_num = 0; det_num < detectors_.detectors.size(); + ++det_num) { - detector_map[volume_ids_[didx]] = DetectorId{didx}; + DetectorId det_id(det_num); + auto& detector = detectors_.detectors[det_num]; + for (auto& volume : detector.volumes) + { + detector_map[volume] = det_id; + } } mirror_ = CollectionMirror{[&] { diff --git a/src/celeritas/user/SDParams.hh b/src/celeritas/user/SDParams.hh index 767ebb8983..0355d34c24 100644 --- a/src/celeritas/user/SDParams.hh +++ b/src/celeritas/user/SDParams.hh @@ -11,13 +11,14 @@ #include "corecel/Assert.hh" #include "corecel/data/CollectionMirror.hh" #include "corecel/data/ParamsDataInterface.hh" +#include "geocel/inp/Model.hh" +#include "celeritas/geo/GeoFwd.hh" #include "SDData.hh" namespace celeritas { //---------------------------------------------------------------------------// -class GeoParamsInterface; //---------------------------------------------------------------------------// /*! @@ -34,17 +35,14 @@ class SDParams final : public ParamsDataInterface //!@} public: - //! Default constructor: no detectors - SDParams() = default; - //! Construct from canonical volume IDs - SDParams(GeoParamsInterface const& geo, VecVolId&& volume_ids); + SDParams(CoreGeoParams const& geo, inp::Detectors detectors); //! Whether any detectors are present bool empty() const { return !static_cast(mirror_); } //! Number of detectors - DetectorId::size_type size() const { return volume_ids_.size(); } + DetectorId::size_type size() const { return detectors_.detectors.size(); } //! Access detector ID based on implementation volume ID DetectorId volume_to_detector_id(ImplVolumeId iv_id) @@ -53,10 +51,10 @@ class SDParams final : public ParamsDataInterface } //! Access volume ID based on detector ID - VolumeId detector_to_volume_id(DetectorId det_id) + std::vector detector_to_volume_id(DetectorId det_id) { CELER_EXPECT(det_id < this->size()); - return volume_ids_[det_id.get()]; + return detectors_.detectors[det_id.get()].volumes; } //!@{ @@ -71,6 +69,8 @@ class SDParams final : public ParamsDataInterface private: VecVolId volume_ids_; CollectionMirror mirror_; + + inp::Detectors detectors_; }; //---------------------------------------------------------------------------// diff --git a/test/celeritas/GlobalTestBase.cc b/test/celeritas/GlobalTestBase.cc index 8a73f81d12..73e4a851dd 100644 --- a/test/celeritas/GlobalTestBase.cc +++ b/test/celeritas/GlobalTestBase.cc @@ -149,6 +149,9 @@ auto GlobalTestBase::build_geometry() -> SPConstCoreGeo celeritas::global_volumes(volume_); surface_ = std::make_shared(mi.surfaces, *volume_); + detector_ = std::make_shared(*core_geo, mi.detectors); + std::cout << "Detector size " << mi.detectors.detectors.size() << std::endl; + return core_geo; } @@ -188,6 +191,7 @@ optical::CoreParams::Input GlobalTestBase::optical_params_input() inp.gen_reg = std::make_shared(); inp.physics = this->optical_physics(); inp.surface_physics = this->optical_surface_physics(); + inp.detectors = this->detector(); inp.cherenkov = this->cherenkov(); inp.scintillation = this->scintillation(); @@ -225,6 +229,7 @@ auto GlobalTestBase::build_core() -> SPConstCore inp.sim = this->sim(); inp.surface = surface_; inp.volume = volume_; + inp.detector = detector_; inp.wentzel = this->wentzel(); inp.action_reg = this->action_reg(); diff --git a/test/celeritas/GlobalTestBase.hh b/test/celeritas/GlobalTestBase.hh index 5d3126c027..c3c8314f91 100644 --- a/test/celeritas/GlobalTestBase.hh +++ b/test/celeritas/GlobalTestBase.hh @@ -18,6 +18,7 @@ #include "celeritas/geo/GeoFwd.hh" #include "celeritas/global/ActionInterface.hh" #include "celeritas/optical/CoreParams.hh" +#include "celeritas/user/SDParams.hh" #include "Test.hh" @@ -90,6 +91,7 @@ class GlobalTestBase : public Test, public LazyGeantGeoManager using SPConstTrackInit = SP; using SPConstSurface = SP; using SPConstVolume = SP; + using SPConstSensDet = SP; using SPConstWentzelOKVI = SP; using SPActionRegistry = SP; @@ -206,6 +208,7 @@ class GlobalTestBase : public Test, public LazyGeantGeoManager // Access surface and volume; called during build_core SPConstSurface const& surface() const { return surface_; } SPConstVolume const& volume() const { return volume_; } + SPConstSensDet const& detector() const { return detector_; } // Implement LazyGeantGeoManager SPConstGeoI build_geo_from_geant(SPConstGeantGeo const&) const final; @@ -241,6 +244,7 @@ class GlobalTestBase : public Test, public LazyGeantGeoManager // NOTE: these may not be built SPConstSurface surface_; SPConstVolume volume_; + SPConstSensDet detector_; SPConstCherenkov cherenkov_; SPActionRegistry optical_action_reg_; diff --git a/test/celeritas/optical/Generator.test.cc b/test/celeritas/optical/Generator.test.cc index ba248b2f39..6e6d010fb1 100644 --- a/test/celeritas/optical/Generator.test.cc +++ b/test/celeritas/optical/Generator.test.cc @@ -157,8 +157,8 @@ TEST_F(LArSphereGeneratorTest, primary_generator) if (reference_configuration) { - EXPECT_EQ(68916, result.steps); - EXPECT_EQ(18, result.step_iters); + EXPECT_EQ(65536, result.steps); + EXPECT_EQ(16, result.step_iters); } EXPECT_EQ(1, result.flushes); ASSERT_EQ(1, result.generators.size()); @@ -241,8 +241,8 @@ TEST_F(LArSphereGeneratorTest, generator) if (reference_configuration) { EXPECT_EQ(51226, gen.num_generated); - EXPECT_EQ(54319, result.steps); - EXPECT_EQ(15, result.step_iters); + EXPECT_EQ(51226, result.steps); + EXPECT_EQ(13, result.step_iters); } // Check accumulated action times diff --git a/test/celeritas/optical/OpticalCollector.test.cc b/test/celeritas/optical/OpticalCollector.test.cc index 7bc87f06d8..44fd2f9e4a 100644 --- a/test/celeritas/optical/OpticalCollector.test.cc +++ b/test/celeritas/optical/OpticalCollector.test.cc @@ -468,10 +468,8 @@ TEST_F(LArSphereOffloadTest, host_generate_small) if (CELERITAS_REAL_TYPE == CELERITAS_REAL_TYPE_DOUBLE) { - constexpr unsigned int expected_steps = using_surface_vg ? 109 : 121; - constexpr unsigned int expected_step_iters = using_surface_vg ? 4 : 5; - EXPECT_EQ(expected_steps, result.accum.steps); - EXPECT_EQ(expected_step_iters, result.accum.step_iters); + EXPECT_EQ(109, result.accum.steps); + EXPECT_EQ(4, result.accum.step_iters); EXPECT_EQ(1, result.accum.flushes); ASSERT_EQ(1, result.accum.generators.size()); @@ -496,10 +494,8 @@ TEST_F(LArSphereOffloadTest, host_generate) if (CELERITAS_REAL_TYPE == CELERITAS_REAL_TYPE_DOUBLE) { - unsigned int expected_steps = using_surface_vg ? 23642 : 25770; - unsigned int expected_step_iters = using_surface_vg ? 1 : 3; - EXPECT_EQ(expected_steps, static_cast(result.accum.steps)); - EXPECT_EQ(expected_step_iters, result.accum.step_iters); + EXPECT_SOFT_NEAR(23642, static_cast(result.accum.steps), 1e-4); + EXPECT_EQ(1, result.accum.step_iters); EXPECT_EQ(1, result.accum.flushes); ASSERT_EQ(1, result.accum.generators.size()); diff --git a/test/celeritas/user/SDParams.test.cc b/test/celeritas/user/SDParams.test.cc index 77c9e35db4..b9c737713f 100644 --- a/test/celeritas/user/SDParams.test.cc +++ b/test/celeritas/user/SDParams.test.cc @@ -14,6 +14,7 @@ #include "corecel/Assert.hh" #include "geocel/VolumeParams.hh" +#include "geocel/inp/Model.hh" #include "celeritas/GlobalTestBase.hh" #include "celeritas/OnlyCoreTestBase.hh" #include "celeritas/OnlyGeoTestBase.hh" @@ -30,50 +31,39 @@ class SDParamsTest : public OnlyGeoTestBase { public: using VecStr = std::vector; - using VecVolId = std::vector; std::string_view gdml_basename() const override { return "testem3-flat"sv; } - VecVolId find_volumes(VecStr const& labels) + // This assigns a unique detector to each volume label passed in + inp::Detectors find_volumes(VecStr const& labels) { auto const& vols = this->volumes(); CELER_VALIDATE(vols, << "volumes were not set up"); - VecVolId result; + inp::Detectors result; auto const& all_vol_labels = vols->volume_labels(); for (auto const& name : labels) { - result.push_back(all_vol_labels.find_unique(name)); - CELER_VALIDATE(result.back(), - << "invalid detector volume " << name); + VolumeId vol_id = all_vol_labels.find_unique(name); + CELER_VALIDATE(vol_id, << "invalid detector volume " << name); + inp::Detector detector; + detector.label = name; + detector.volumes.push_back(vol_id); + result.detectors.push_back(detector); } return result; } }; -TEST_F(SDParamsTest, empty_constructor_test) -{ - SDParams params; - EXPECT_TRUE(params.empty()); - - if (CELERITAS_DEBUG) - { - auto det_id = DetectorId{0}; - auto vol_id = ImplVolumeId{0}; - EXPECT_THROW(params.volume_to_detector_id(vol_id), - celeritas::DebugError); - EXPECT_THROW(params.detector_to_volume_id(det_id), - celeritas::DebugError); - } -} - -TEST_F(SDParamsTest, TEST_IF_CELERITAS_DEBUG(invalid_label_test)) +TEST_F(SDParamsTest, TEST_IF_CELERITAS_DEBUG(no_label_test)) { auto const& geo = *this->geometry(); - EXPECT_THROW(SDParams(geo, {VolumeId{}}), celeritas::RuntimeError); + inp::Detectors detectors; + SDParams params(geo, detectors); + EXPECT_EQ(0, params.size()); } TEST_F(SDParamsTest, detector_test) @@ -87,13 +77,24 @@ TEST_F(SDParamsTest, detector_test) EXPECT_FALSE(params.empty()); EXPECT_EQ(3, params.size()); - for (auto iv_id : range(ImplVolumeId{impl_volumes.size()})) + for (auto iv_id : + range(ImplVolumeId{static_cast(impl_volumes.size())})) { auto det_id = params.volume_to_detector_id(iv_id); if (det_id) { EXPECT_EQ(detector_labels[det_id.get()], this->geometry()->impl_volumes().at(iv_id).name); + + std::vector vol_ids + = params.detector_to_volume_id(det_id); + auto vol_id = id_cast(iv_id.get()); + EXPECT_NE(std::find_if(vol_ids.begin(), + vol_ids.end(), + [vol_id](VolumeId const& v_id) { + return v_id.get() == vol_id.get(); + }), + vol_ids.end()); } } }