From 549d4b0cf0b9e6e44c38e71912494fa6d256e73b Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Thu, 28 Aug 2025 15:52:35 -0500 Subject: [PATCH 01/22] Initial draft of surface normals --- .../optical/surface/SurfacePhysicsData.hh | 13 ++- .../optical/surface/SurfacePhysicsParams.cc | 2 +- .../optical/surface/SurfacePhysicsView.hh | 79 ++++++++++++++++++ .../surface/detail/InitBoundaryExecutor.hh | 13 ++- src/celeritas/phys/SurfacePhysicsMapView.hh | 11 ++- test/celeritas/optical/SurfacePhysics.test.cc | 80 ++++++++++++++++++- 6 files changed, 177 insertions(+), 21 deletions(-) diff --git a/src/celeritas/optical/surface/SurfacePhysicsData.hh b/src/celeritas/optical/surface/SurfacePhysicsData.hh index 7675b851d2..19ab70aa89 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsData.hh +++ b/src/celeritas/optical/surface/SurfacePhysicsData.hh @@ -143,17 +143,22 @@ struct SurfacePhysicsStateData StateItems surface; StateItems surface_orientation; - StateItems surface_position; + StateItems global_normal; StateItems pre_volume_material; StateItems post_volume_material; + StateItems surface_position; + StateItems facet_normal; + //! Whether data is assigned explicit CELER_FUNCTION operator bool() const { return !surface.empty() && surface.size() == surface_orientation.size() && surface.size() == surface_position.size() && surface.size() == pre_volume_material.size() - && surface.size() == post_volume_material.size(); + && surface.size() == post_volume_material.size() + && surface.size() == global_normal.size() + && surface.size() == facet_normal.size(); } //! State size @@ -167,9 +172,11 @@ struct SurfacePhysicsStateData CELER_EXPECT(other); surface = other.surface; surface_orientation = other.surface_orientation; + global_normal = other.global_normal; surface_position = other.surface_position; pre_volume_material = other.pre_volume_material; post_volume_material = other.post_volume_material; + facet_normal = other.facet_normal; return *this; } }; @@ -187,9 +194,11 @@ resize(SurfacePhysicsStateData* state, size_type size) resize(&state->surface, size); resize(&state->surface_orientation, size); + resize(&state->global_normal, size); resize(&state->surface_position, size); resize(&state->pre_volume_material, size); resize(&state->post_volume_material, size); + resize(&state->facet_normal, size); CELER_ENSURE(*state); CELER_ENSURE(state->size() == size); diff --git a/src/celeritas/optical/surface/SurfacePhysicsParams.cc b/src/celeritas/optical/surface/SurfacePhysicsParams.cc index d4a89a5264..563f2d4207 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsParams.cc +++ b/src/celeritas/optical/surface/SurfacePhysicsParams.cc @@ -154,7 +154,7 @@ SurfacePhysicsParams::SurfacePhysicsParams(ActionRegistry* action_reg, //---------------------------------------------------------------------------// /*! - * Build surface data from inputs. + * Build surface data form inputs. */ void SurfacePhysicsParams::build_surfaces( std::vector> const& interstitial_materials, diff --git a/src/celeritas/optical/surface/SurfacePhysicsView.hh b/src/celeritas/optical/surface/SurfacePhysicsView.hh index 53460a785a..4ec789299b 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsView.hh +++ b/src/celeritas/optical/surface/SurfacePhysicsView.hh @@ -6,9 +6,12 @@ //---------------------------------------------------------------------------// #pragma once +#include "corecel/math/ArrayUtils.hh" #include "celeritas/optical/Types.hh" +#include "celeritas/phys/SurfacePhysicsMapView.hh" #include "SurfacePhysicsData.hh" +#include "SurfacePhysicsUtils.hh" namespace celeritas { @@ -36,6 +39,7 @@ class SurfacePhysicsView { SurfaceId surface{}; SubsurfaceDirection orientation; + Real3 global_normal{0, 0, 0}; OptMatId pre_volume_material{}; OptMatId post_volume_material{}; }; @@ -62,6 +66,9 @@ class SurfacePhysicsView // Get surface orientation inline CELER_FUNCTION SubsurfaceDirection orientation() const; + // Get global surface normal + inline CELER_FUNCTION Real3 const& global_normal() const; + //// QUERY CROSSING STATE //// // Whether track is undergoing boundary crossing @@ -94,6 +101,21 @@ class SurfacePhysicsView inline CELER_FUNCTION PhysSurfaceId subsurface_interface(SubsurfaceDirection) const; + // Calculate traversal direction from track momentum + inline CELER_FUNCTION SubsurfaceDirection + traversal_direction(Real3 const&) const; + + // Get surface model map for the given step and physics surface + inline CELER_FUNCTION + SurfacePhysicsMapView surface_physics_map(SurfacePhysicsOrder, + PhysSurfaceId) const; + + // Get local facet normal + inline CELER_FUNCTION Real3 const& facet_normal() const; + + // Assign local facet normal + inline CELER_FUNCTION void facet_normal(Real3 const&); + //// MUTATORS //// // Cross subsurface interface in the given direction (track-local) @@ -150,8 +172,11 @@ CELER_FUNCTION SurfacePhysicsView& SurfacePhysicsView::operator=(Initializer const& init) { CELER_EXPECT(init.surface); + CELER_EXPECT(is_soft_unit_vector(init.global_normal)); states_.surface[track_id_] = init.surface; states_.surface_orientation[track_id_] = init.orientation; + states_.global_normal[track_id_] = init.global_normal; + states_.facet_normal[track_id_] = init.global_normal; states_.surface_position[track_id_] = SurfaceTrackPosition{0}; states_.pre_volume_material[track_id_] = init.pre_volume_material; states_.post_volume_material[track_id_] = init.post_volume_material; @@ -194,6 +219,19 @@ CELER_FUNCTION SubsurfaceDirection SurfacePhysicsView::orientation() const return states_.surface_orientation[track_id_]; } +//---------------------------------------------------------------------------// +/*! + * Get global surface normal. + * + * The global surface normal is the normal defined by the geometry and does not + * include any roughness effects. By convention it points from the post-volume + * into the pre-volume. + */ +CELER_FUNCTION Real3 const& SurfacePhysicsView::global_normal() const +{ + return states_.global_normal[track_id_]; +} + //---------------------------------------------------------------------------// /*! * Whether the track is undergoing boundary crossing. @@ -318,6 +356,47 @@ SurfacePhysicsView::subsurface_interface(SubsurfaceDirection d) const this->surface_record().subsurface_interfaces); } +//---------------------------------------------------------------------------// +/*! + * Calculate traversal direction from track momentum. + */ +CELER_FUNCTION SubsurfaceDirection +SurfacePhysicsView::traversal_direction(Real3 const& dir) const +{ + CELER_EXPECT(is_soft_unit_vector(dir)); + return static_cast( + is_entering_surface(dir, this->global_normal())); +} + +//---------------------------------------------------------------------------// +/*! + * Get surface model map for the given step and physics surface + */ +CELER_FUNCTION SurfacePhysicsMapView SurfacePhysicsView::surface_physics_map( + SurfacePhysicsOrder step, PhysSurfaceId surface) const +{ + return SurfacePhysicsMapView{params_.model_maps[step], surface}; +} + +//---------------------------------------------------------------------------// +/*! + * Get local facet normal after roughness sampling. + */ +CELER_FUNCTION Real3 const& SurfacePhysicsView::facet_normal() const +{ + return states_.facet_normal[track_id_]; +} + +//---------------------------------------------------------------------------// +/*! + * Assign local facet normal from roughness sampling. + */ +CELER_FUNCTION void SurfacePhysicsView::facet_normal(Real3 const& normal) +{ + CELER_EXPECT(is_soft_unit_vector(normal)); + states_.facet_normal[track_id_] = normal; +} + //---------------------------------------------------------------------------// /*! * Cross the subsurface interface in the given direction. diff --git a/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh b/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh index cba01940ca..c399bfa43d 100644 --- a/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh +++ b/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh @@ -77,14 +77,6 @@ CELER_FUNCTION void InitBoundaryExecutor::operator()(CoreTrackView& track) const = select_surface(track.surface(), geo.volume_instance_id()); if (!oriented_surface) { - // Kill the track if the post-volume doesn't have a valid optical - // material and there's no surface - if (!post_volume_material) - { - track.sim().status(TrackStatus::killed); - return; - } - // Use default surface data oriented_surface.surface = surface_physics.default_surface(); oriented_surface.orientation = SubsurfaceDirection::forward; @@ -93,8 +85,13 @@ CELER_FUNCTION void InitBoundaryExecutor::operator()(CoreTrackView& track) const surface_physics = SurfacePhysicsView::Initializer{oriented_surface.surface, oriented_surface.orientation, + geo.normal(), pre_volume_material, post_volume_material}; + + CELER_ASSERT( + is_entering_surface(geo.dir(), surface_physics.global_normal())); + // TODO: replace with surface stepping action when implemented track.sim().post_step_action(surface_physics.post_boundary_action()); } diff --git a/src/celeritas/phys/SurfacePhysicsMapView.hh b/src/celeritas/phys/SurfacePhysicsMapView.hh index f98627910f..d953f65d03 100644 --- a/src/celeritas/phys/SurfacePhysicsMapView.hh +++ b/src/celeritas/phys/SurfacePhysicsMapView.hh @@ -30,22 +30,21 @@ class SurfacePhysicsMapView public: // Construct from data and current surface - CELER_FUNCTION - SurfacePhysicsMapView(SurfaceParamsRef const& params, - PhysSurfaceId surface); + inline CELER_FUNCTION SurfacePhysicsMapView(SurfaceParamsRef const& params, + PhysSurfaceId surface); // Construct from data and "default" surface - explicit CELER_FUNCTION + explicit inline CELER_FUNCTION SurfacePhysicsMapView(SurfaceParamsRef const& params); // Get the model ID for the current surface, if any - CELER_FUNCTION SurfaceModelId surface_model_id() const; + inline CELER_FUNCTION SurfaceModelId surface_model_id() const; //! Current physics surface ID CELER_FUNCTION PhysSurfaceId surface_id() const { return surface_; } // Get the subindex inside that model - CELER_FUNCTION InternalSurfaceId internal_surface_id() const; + inline CELER_FUNCTION InternalSurfaceId internal_surface_id() const; private: SurfaceParamsRef const& params_; diff --git a/test/celeritas/optical/SurfacePhysics.test.cc b/test/celeritas/optical/SurfacePhysics.test.cc index 201c9822a8..d79cecad8c 100644 --- a/test/celeritas/optical/SurfacePhysics.test.cc +++ b/test/celeritas/optical/SurfacePhysics.test.cc @@ -379,6 +379,7 @@ TEST_F(SurfacePhysicsTest, init_surface_physics_view) this->surface_physics_view(TrackSlotId(track)) = SurfacePhysicsView::Initializer{expected_surfaces[track], expected_orientations[track], + Real3{0, 0, -1}, OptMatId{0}, OptMatId{1}}; } @@ -470,7 +471,7 @@ TEST_F(SurfacePhysicsTest, traverse_subsurface) auto s_physics = this->surface_physics_view(TrackSlotId{0}); s_physics = SurfacePhysicsView::Initializer{ - SurfaceId{2}, forward, OptMatId{0}, OptMatId{1}}; + SurfaceId{2}, forward, Real3{0, 0, -1}, OptMatId{0}, OptMatId{1}}; EXPECT_TRUE(s_physics.is_crossing_boundary()); EXPECT_TRUE(s_physics.in_pre_volume()); @@ -499,7 +500,7 @@ TEST_F(SurfacePhysicsTest, traverse_subsurface) auto s_physics = this->surface_physics_view(TrackSlotId{1}); s_physics = SurfacePhysicsView::Initializer{ - SurfaceId{2}, reverse, OptMatId{1}, OptMatId{0}}; + SurfaceId{2}, reverse, Real3{0, 0, -1}, OptMatId{1}, OptMatId{0}}; EXPECT_TRUE(s_physics.is_crossing_boundary()); EXPECT_TRUE(s_physics.in_pre_volume()); @@ -537,7 +538,7 @@ TEST_F(SurfacePhysicsTest, traverse_subsurface) auto s_physics = this->surface_physics_view(TrackSlotId{2}); s_physics = SurfacePhysicsView::Initializer{ - SurfaceId{0}, forward, OptMatId{0}, OptMatId{1}}; + SurfaceId{0}, forward, Real3{0, 0, -1}, OptMatId{0}, OptMatId{1}}; EXPECT_TRUE(s_physics.is_crossing_boundary()); EXPECT_TRUE(s_physics.in_pre_volume()); @@ -572,7 +573,7 @@ TEST_F(SurfacePhysicsTest, traverse_subsurface) auto s_physics = this->surface_physics_view(TrackSlotId{3}); s_physics = SurfacePhysicsView::Initializer{ - SurfaceId{1}, reverse, OptMatId{1}, OptMatId{0}}; + SurfaceId{1}, reverse, Real3{0, 0, -1}, OptMatId{1}, OptMatId{0}}; EXPECT_TRUE(s_physics.is_crossing_boundary()); EXPECT_TRUE(s_physics.in_pre_volume()); @@ -595,6 +596,77 @@ TEST_F(SurfacePhysicsTest, traverse_subsurface) } } +//---------------------------------------------------------------------------// +// Test track geometry to direction conversion +TEST_F(SurfacePhysicsTest, traversal_direction) +{ + [[maybe_unused]] auto params = this->optical_surface_physics(); + this->initialize_states(10); + + { + auto s_physics = this->surface_physics_view(TrackSlotId{2}); + s_physics = SurfacePhysicsView::Initializer{ + SurfaceId{1}, + forward, + make_unit_vector(Real3{-1, 2, 3}), + OptMatId{0}, + OptMatId{1}}; + + std::vector geo_directions{ + make_unit_vector(Real3{1, 0, 1}), + make_unit_vector(Real3{-1, 2, 3}), + make_unit_vector(Real3{-3, -4, -1}), + make_unit_vector(Real3{1, 0, 0}), + }; + + std::vector directions; + for (auto const& dir : geo_directions) + { + directions.push_back(s_physics.traversal_direction(dir)); + } + + std::vector expected_directions{ + reverse, + reverse, + forward, + forward, + }; + + EXPECT_VEC_EQ(expected_directions, directions); + } + { + auto s_physics = this->surface_physics_view(TrackSlotId{3}); + s_physics + = SurfacePhysicsView::Initializer{SurfaceId{2}, + reverse, + make_unit_vector(Real3{1, 1, 1}), + OptMatId{1}, + OptMatId{0}}; + + std::vector geo_directions{ + make_unit_vector(Real3{-1, -1, -1}), + make_unit_vector(Real3{-1, 2, 3}), + make_unit_vector(Real3{-3, -4, -1}), + make_unit_vector(Real3{0, 0, 1}), + }; + + std::vector directions; + for (auto const& dir : geo_directions) + { + directions.push_back(s_physics.traversal_direction(dir)); + } + + std::vector expected_directions{ + forward, + reverse, + forward, + reverse, + }; + + EXPECT_VEC_EQ(expected_directions, directions); + } +} + //---------------------------------------------------------------------------// } // namespace test } // namespace optical From 65c4f11412768b5f4bd51a351f36e77d2b1a6350 Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Thu, 28 Aug 2025 17:32:52 -0500 Subject: [PATCH 02/22] Disabled some tests not using ORANGE --- app/celer-sim/CMakeLists.txt | 5 +++++ test/celeritas/CMakeLists.txt | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/app/celer-sim/CMakeLists.txt b/app/celer-sim/CMakeLists.txt index ea3b652213..77b74a4ac9 100644 --- a/app/celer-sim/CMakeLists.txt +++ b/app/celer-sim/CMakeLists.txt @@ -133,4 +133,9 @@ celer_sim_test(lar lar-sphere.gdml gamma-4evt-15prim.hepmc3 lar-mctruth.root ) +if(NOT CELERITAS_CORE_GEO STREQUAL "ORANGE") + set_tests_properties("app/celer-sim:lar:cpu" PROPERTIES DISABLED True) + set_tests_properties("app/celer-sim:lar:gpu" PROPERTIES DISABLED True) +endif() + #-----------------------------------------------------------------------------# diff --git a/test/celeritas/CMakeLists.txt b/test/celeritas/CMakeLists.txt index df54010341..b9ebede8b1 100644 --- a/test/celeritas/CMakeLists.txt +++ b/test/celeritas/CMakeLists.txt @@ -37,8 +37,10 @@ if(CELERITAS_CORE_GEO STREQUAL "ORANGE") set(_needs_not_orange DISABLE) set(_core_geo_libs testcel_orange Celeritas::orange) elseif(CELERITAS_CORE_GEO STREQUAL "VecGeom") + set(_needs_orange DISABLE) set(_core_geo_libs testcel_geocel ${VecGeom_LIBRARIES}) elseif(CELERITAS_CORE_GEO STREQUAL "Geant4") + set(_needs_orange DISABLE) set(_core_geo_libs testcel_geocel ${Geant4_LIBRARIES}) endif() @@ -395,9 +397,9 @@ celeritas_add_test(optical/ImportedModelAdapter.test.cc) celeritas_add_test(optical/ImportedMaterials.test.cc) celeritas_add_test(optical/ModelImporter.test.cc) celeritas_add_test(optical/MfpBuilder.test.cc) -celeritas_add_test(optical/OpticalCollector.test.cc GPU ${_needs_geant4}) +celeritas_add_test(optical/OpticalCollector.test.cc GPU ${_needs_geant4} ${_needs_orange}) celeritas_add_test(optical/OpticalUtils.test.cc GPU) -celeritas_add_test(optical/PrimaryGenerator.test.cc GPU ${_needs_geant4}) +celeritas_add_test(optical/PrimaryGenerator.test.cc GPU ${_needs_geant4} ${_needs_orange}) celeritas_add_test(optical/Rayleigh.test.cc) celeritas_add_test(optical/RayleighMfpCalculator.test.cc) celeritas_add_test(optical/RoughnessCalculator.test.cc) From 42e220bc2f1f16a0bfa72ce36a2ee6d880de9738 Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Tue, 9 Sep 2025 02:57:41 -0500 Subject: [PATCH 03/22] Revert regressions --- src/celeritas/optical/surface/SurfacePhysicsParams.cc | 2 +- .../optical/surface/detail/InitBoundaryExecutor.hh | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/celeritas/optical/surface/SurfacePhysicsParams.cc b/src/celeritas/optical/surface/SurfacePhysicsParams.cc index 563f2d4207..d4a89a5264 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsParams.cc +++ b/src/celeritas/optical/surface/SurfacePhysicsParams.cc @@ -154,7 +154,7 @@ SurfacePhysicsParams::SurfacePhysicsParams(ActionRegistry* action_reg, //---------------------------------------------------------------------------// /*! - * Build surface data form inputs. + * Build surface data from inputs. */ void SurfacePhysicsParams::build_surfaces( std::vector> const& interstitial_materials, diff --git a/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh b/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh index c399bfa43d..83ef20b7c7 100644 --- a/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh +++ b/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh @@ -77,6 +77,14 @@ CELER_FUNCTION void InitBoundaryExecutor::operator()(CoreTrackView& track) const = select_surface(track.surface(), geo.volume_instance_id()); if (!oriented_surface) { + // Kill the track if the post-volume doesn't have a valid optical + // material and there's no surface + if (!post_volume_material) + { + track.sim().status(TrackStatus::killed); + return; + } + // Use default surface data oriented_surface.surface = surface_physics.default_surface(); oriented_surface.orientation = SubsurfaceDirection::forward; From f58138f0d233144a0084f539298a49cb8e524035 Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Fri, 29 Aug 2025 08:27:27 -0500 Subject: [PATCH 04/22] Polished and Smear roughness models --- src/celeritas/CMakeLists.txt | 3 + .../optical/surface/SurfaceModelView.hh | 44 ++++++++++++ .../model/PolishedRoughnessExecutor.hh | 55 ++++++++++++++ .../surface/model/PolishedRoughnessModel.cc | 60 ++++++++++++++++ .../surface/model/PolishedRoughnessModel.cu | 14 ++++ .../surface/model/PolishedRoughnessModel.hh | 46 ++++++++++++ .../surface/model/SmearRoughnessData.hh | 62 ++++++++++++++++ .../surface/model/SmearRoughnessExecutor.hh | 70 ++++++++++++++++++ .../surface/model/SmearRoughnessModel.cc | 71 +++++++++++++++++++ .../surface/model/SmearRoughnessModel.cu | 14 ++++ .../surface/model/SmearRoughnessModel.hh | 49 +++++++++++++ 11 files changed, 488 insertions(+) create mode 100644 src/celeritas/optical/surface/SurfaceModelView.hh create mode 100644 src/celeritas/optical/surface/model/PolishedRoughnessExecutor.hh create mode 100644 src/celeritas/optical/surface/model/PolishedRoughnessModel.cc create mode 100644 src/celeritas/optical/surface/model/PolishedRoughnessModel.cu create mode 100644 src/celeritas/optical/surface/model/PolishedRoughnessModel.hh create mode 100644 src/celeritas/optical/surface/model/SmearRoughnessData.hh create mode 100644 src/celeritas/optical/surface/model/SmearRoughnessExecutor.hh create mode 100644 src/celeritas/optical/surface/model/SmearRoughnessModel.cc create mode 100644 src/celeritas/optical/surface/model/SmearRoughnessModel.cu create mode 100644 src/celeritas/optical/surface/model/SmearRoughnessModel.hh diff --git a/src/celeritas/CMakeLists.txt b/src/celeritas/CMakeLists.txt index 98c90f5d1a..ac6249cb7d 100644 --- a/src/celeritas/CMakeLists.txt +++ b/src/celeritas/CMakeLists.txt @@ -363,6 +363,9 @@ celeritas_polysource(optical/gen/PrimaryGeneratorAction) celeritas_polysource(optical/gen/detail/GeneratorAlgorithms) celeritas_polysource(optical/gen/detail/OffloadAlgorithms) celeritas_polysource(optical/surface/BoundaryAction) +celeritas_polysource(optical/surface/model/GaussianRoughnessModel) +celeritas_polysource(optical/surface/model/PolishedRoughnessModel) +celeritas_polysource(optical/surface/model/SmearRoughnessModel) celeritas_polysource(phys/detail/DiscreteSelectAction) celeritas_polysource(phys/detail/PreStepAction) celeritas_polysource(phys/detail/TrackingCutAction) diff --git a/src/celeritas/optical/surface/SurfaceModelView.hh b/src/celeritas/optical/surface/SurfaceModelView.hh new file mode 100644 index 0000000000..aceb368ab7 --- /dev/null +++ b/src/celeritas/optical/surface/SurfaceModelView.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/surface/SurfaceModelView.hh +//---------------------------------------------------------------------------// +#pragma once + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// +/*! + * Brief class description. + * + * Optional detailed class description, and possibly example usage: + * \code + SurfaceModelView ...; + \endcode + */ +class SurfaceModelView +{ + public: + //!@{ + //! \name Type aliases + //!@} + + public: + inline CELER_FUNCTION SubsurfaceDirection direction() const; + inline CELER_FUNCTION PhysSurfaceId phys_surface_id() const; + inline CELER_FUNCTION SurfaceModelId surface_model() const; + inline CELER_FUNCTION InternalSurfaceId internal_surface_id() const; +}; + +//---------------------------------------------------------------------------// +// INLINE DEFINITIONS +//---------------------------------------------------------------------------// +/*! + */ + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessExecutor.hh b/src/celeritas/optical/surface/model/PolishedRoughnessExecutor.hh new file mode 100644 index 0000000000..9cd5b34b3b --- /dev/null +++ b/src/celeritas/optical/surface/model/PolishedRoughnessExecutor.hh @@ -0,0 +1,55 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/PolishedRoughnessExecutor.hh +//---------------------------------------------------------------------------// +#pragma once + +#include "corecel/math/ArrayOperators.hh" +#include "celeritas/optical/CoreTrackView.hh" +#include "celeritas/optical/surface/SurfacePhysicsUtils.hh" + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// +/*! + * Brief class description. + * + * Optional detailed class description, and possibly example usage: + * \code + PolishedRoughnessExecutor ...; + \endcode + */ +struct PolishedRoughnessExecutor +{ + inline CELER_FUNCTION void operator()(CoreTrackView& track) const; +}; + +//---------------------------------------------------------------------------// +// INLINE DEFINITIONS +//---------------------------------------------------------------------------// +/*! + */ +CELER_FUNCTION void +PolishedRoughnessExecutor::operator()(CoreTrackView& track) const +{ + auto s_physics = track.surface_physics(); + + auto dir = s_physics.traversal_direction(track.geometry().dir()); + CELER_ASSERT(!s_physics.is_exiting(dir)); + + Real3 normal = s_physics.global_normal(); + if (dir == SubsurfaceDirection::reverse) + { + normal = -normal; + } + + s_physics.facet_normal(normal); +} + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc new file mode 100644 index 0000000000..32266924f4 --- /dev/null +++ b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc @@ -0,0 +1,60 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/PolishedRoughnessModel.cc +//---------------------------------------------------------------------------// +#include "PolishedRoughnessModel.hh" + +#include "corecel/data/CollectionBuilder.hh" +#include "celeritas/optical/CoreParams.hh" +#include "celeritas/optical/CoreState.hh" +#include "celeritas/optical/action/ActionLauncher.hh" +#include "celeritas/optical/surface/TrackSlotExecutor.hh" + +#include "PolishedRoughnessExecutor.hh" + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// +/*! + * + */ +PolishedRoughnessModel::PolishedRoughnessModel( + SurfaceModelId model, + std::map const& layer_map) + : SurfaceModel(model, "polished") +{ + for (auto const& [surface, polished] : layer_map) + { + CELER_EXPECT(surface); + surfaces_.push_back(surface); + } +} + +std::vector PolishedRoughnessModel::get_surfaces() const +{ + return surfaces_; +} + +void PolishedRoughnessModel::step(CoreParams const& params, + CoreStateHost& state) const +{ + launch_action(state, + make_surface_physics_executor(params.ptr(), + state.ptr(), + SurfacePhysicsOrder::roughness, + this->surface_model_id(), + PolishedRoughnessExecutor{})); +} + +void PolishedRoughnessModel::step(CoreParams const&, CoreStateDevice&) const +{ + CELER_NOT_IMPLEMENTED("CUDA OR HIP"); +} + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cu b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cu new file mode 100644 index 0000000000..1e5f4aa678 --- /dev/null +++ b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cu @@ -0,0 +1,14 @@ +//------------------------------ -*- cuda -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/PolishedRoughnessModel.cu +//---------------------------------------------------------------------------// +#include "PolishedRoughnessModel.hh" + +namespace celeritas +{ +//---------------------------------------------------------------------------// + +//---------------------------------------------------------------------------// +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh b/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh new file mode 100644 index 0000000000..a3c6f8895e --- /dev/null +++ b/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh @@ -0,0 +1,46 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/PolishedRoughnessModel.hh +//---------------------------------------------------------------------------// +#pragma once + +#include "corecel/data/CollectionMirror.hh" +#include "celeritas/inp/SurfacePhysics.hh" +#include "celeritas/optical/surface/SurfaceModel.hh" + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// +/*! + * Brief class description. + * + * Optional detailed class description, and possibly example usage: + * \code + PolishedRoughnessModel ...; + \endcode + */ +class PolishedRoughnessModel : public SurfaceModel +{ + public: + //!@{ + //! \name Type aliases + //!@} + + public: + PolishedRoughnessModel(SurfaceModelId, + std::map const&); + std::vector get_surfaces() const final; + void step(CoreParams const&, CoreStateHost&) const final; + void step(CoreParams const&, CoreStateDevice&) const final; + + private: + std::vector surfaces_; +}; + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/SmearRoughnessData.hh b/src/celeritas/optical/surface/model/SmearRoughnessData.hh new file mode 100644 index 0000000000..fea281e532 --- /dev/null +++ b/src/celeritas/optical/surface/model/SmearRoughnessData.hh @@ -0,0 +1,62 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/SmearRoughnessData.hh +//---------------------------------------------------------------------------// +#pragma once + +#include "corecel/Macros.hh" +#include "corecel/data/Collection.hh" +#include "celeritas/Types.hh" +#include "celeritas/optical/surface/SurfaceModel.hh" + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// +/*! + * Brief class description. + * + * Optional detailed class description, and possibly example usage: + * \code + SmearRoughnessData ...; + \endcode + */ +template +struct SmearRoughnessData +{ + //!@{ + //! \name Type aliases + template + using SurfaceItems = Collection; + //!@} + + //// DATA ///// + + SurfaceItems roughness; + + //// METHODS //// + + //! True if assigned + explicit CELER_FUNCTION operator bool() const + { + return !roughness.empty(); + } + + //! Assign from another set of data + template + SmearRoughnessData& operator=(SmearRoughnessData const& other) + { + CELER_EXPECT(other); + + roughness = other.roughness; + + return *this; + } +}; + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/SmearRoughnessExecutor.hh b/src/celeritas/optical/surface/model/SmearRoughnessExecutor.hh new file mode 100644 index 0000000000..0ff47bd7bb --- /dev/null +++ b/src/celeritas/optical/surface/model/SmearRoughnessExecutor.hh @@ -0,0 +1,70 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/SmearRoughnessExecutor.hh +//---------------------------------------------------------------------------// +#pragma once + +#include "corecel/math/ArrayOperators.hh" +#include "celeritas/optical/CoreTrackView.hh" +#include "celeritas/optical/surface/SmearRoughnessSampler.hh" +#include "celeritas/optical/surface/SurfacePhysicsUtils.hh" + +#include "SmearRoughnessData.hh" + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// +/*! + * Brief class description. + * + * Optional detailed class description, and possibly example usage: + * \code + SmearRoughnessExecutor ...; + \endcode + */ +struct SmearRoughnessExecutor +{ + NativeCRef data; + + inline CELER_FUNCTION void operator()(CoreTrackView& track) const; +}; + +//---------------------------------------------------------------------------// +// INLINE DEFINITIONS +//---------------------------------------------------------------------------// +/*! + */ +CELER_FUNCTION void +SmearRoughnessExecutor::operator()(CoreTrackView& track) const +{ + auto s_physics = track.surface_physics(); + + auto dir = s_physics.traversal_direction(track.geometry().dir()); + CELER_ASSERT(!s_physics.is_exiting(dir)); + + Real3 normal = s_physics.global_normal(); + if (dir == SubsurfaceDirection::reverse) + { + normal = -normal; + } + + auto rng = track.rng(); + + auto phys_surface_id = s_physics.subsurface_interface(dir); + auto facet_normal = SmearRoughnessSampler{ + normal, + data.roughness[s_physics + .surface_physics_map(SurfacePhysicsOrder::roughness, + phys_surface_id) + .internal_surface_id()]}(rng); + + s_physics.facet_normal(facet_normal); +} + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/SmearRoughnessModel.cc b/src/celeritas/optical/surface/model/SmearRoughnessModel.cc new file mode 100644 index 0000000000..4487454e2f --- /dev/null +++ b/src/celeritas/optical/surface/model/SmearRoughnessModel.cc @@ -0,0 +1,71 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/SmearRoughnessModel.cc +//---------------------------------------------------------------------------// +#include "SmearRoughnessModel.hh" + +#include "corecel/data/CollectionBuilder.hh" +#include "celeritas/optical/CoreParams.hh" +#include "celeritas/optical/CoreState.hh" +#include "celeritas/optical/action/ActionLauncher.hh" +#include "celeritas/optical/surface/TrackSlotExecutor.hh" + +#include "SmearRoughnessExecutor.hh" + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// +/*! + */ +SmearRoughnessModel::SmearRoughnessModel( + SurfaceModelId model, + std::map const& layer_map) + : SurfaceModel(model, "smear") +{ + HostVal data; + + auto build_roughness = make_builder(&data.roughness); + + for (auto const& [surface, smear] : layer_map) + { + CELER_EXPECT(surface); + surfaces_.push_back(surface); + + CELER_EXPECT(smear); + build_roughness.push_back(smear.roughness); + } + + CELER_ENSURE(data); + + data_ = CollectionMirror{std::move(data)}; +} + +std::vector SmearRoughnessModel::get_surfaces() const +{ + return surfaces_; +} + +void SmearRoughnessModel::step(CoreParams const& params, + CoreStateHost& state) const +{ + launch_action(state, + make_surface_physics_executor( + params.ptr(), + state.ptr(), + SurfacePhysicsOrder::roughness, + this->surface_model_id(), + SmearRoughnessExecutor{data_.host_ref()})); +} + +void SmearRoughnessModel::step(CoreParams const&, CoreStateDevice&) const +{ + CELER_NOT_IMPLEMENTED("CUDA OR HIP"); +} + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/SmearRoughnessModel.cu b/src/celeritas/optical/surface/model/SmearRoughnessModel.cu new file mode 100644 index 0000000000..5dd49b7c12 --- /dev/null +++ b/src/celeritas/optical/surface/model/SmearRoughnessModel.cu @@ -0,0 +1,14 @@ +//------------------------------ -*- cuda -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/SmearRoughnessModel.cu +//---------------------------------------------------------------------------// +#include "SmearRoughnessModel.hh" + +namespace celeritas +{ +//---------------------------------------------------------------------------// + +//---------------------------------------------------------------------------// +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/SmearRoughnessModel.hh b/src/celeritas/optical/surface/model/SmearRoughnessModel.hh new file mode 100644 index 0000000000..d3c8a005d2 --- /dev/null +++ b/src/celeritas/optical/surface/model/SmearRoughnessModel.hh @@ -0,0 +1,49 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/SmearRoughnessModel.hh +//---------------------------------------------------------------------------// +#pragma once + +#include "corecel/data/CollectionMirror.hh" +#include "celeritas/inp/SurfacePhysics.hh" +#include "celeritas/optical/surface/SurfaceModel.hh" + +#include "SmearRoughnessData.hh" + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// +/*! + * Brief class description. + * + * Optional detailed class description, and possibly example usage: + * \code + SmearRoughnessModel ...; + \endcode + */ +class SmearRoughnessModel : public SurfaceModel +{ + public: + //!@{ + //! \name Type aliases + //!@} + + public: + SmearRoughnessModel(SurfaceModelId, + std::map const&); + std::vector get_surfaces() const final; + void step(CoreParams const&, CoreStateHost&) const final; + void step(CoreParams const&, CoreStateDevice&) const final; + + private: + std::vector surfaces_; + CollectionMirror data_; +}; + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas From 5a6c4ef6f899f90e8fee5529e15356f207bb05cc Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Fri, 29 Aug 2025 15:07:55 -0500 Subject: [PATCH 05/22] Saving progress after fixing some weird bugs --- src/celeritas/CMakeLists.txt | 5 +- src/celeritas/optical/CoreParams.cc | 10 +++ src/celeritas/optical/CoreTrackView.hh | 22 +++++ .../optical/action/ActionLauncher.device.hh | 20 ++--- .../action/detail/AlongStepExecutor.hh | 5 ++ .../optical/action/detail/PreStepExecutor.hh | 5 ++ .../action/detail/PropagateExecutor.hh | 5 ++ .../action/detail/TrackingCutExecutor.hh | 5 ++ .../surface/GaussianRoughnessSampler.hh | 4 +- .../optical/surface/SurfaceModelView.hh | 45 +++++++++- .../optical/surface/SurfacePhysicsParams.cc | 42 ++++++--- .../optical/surface/SurfacePhysicsParams.hh | 12 +++ .../optical/surface/SurfacePhysicsView.hh | 44 +++++++++- .../optical/surface/TrackSlotExecutor.hh | 67 ++++++++++++++ .../optical/surface/VolumeSurfaceSelector.hh | 8 +- .../surface/detail/InitBoundaryExecutor.hh | 12 +++ .../optical/surface/model/ControllerImpl.cc | 47 ++++++++++ .../optical/surface/model/FakeExecutor.hh | 19 ++++ .../model/GaussianRoughnessExecutor.hh | 40 +++++++++ .../surface/model/GaussianRoughnessModel.hh | 43 +++++++++ .../model/PolishedRoughnessExecutor.hh | 41 +++------ .../surface/model/PolishedRoughnessModel.cu | 14 --- .../surface/model/PolishedRoughnessModel.hh | 31 +++---- .../optical/surface/model/RoughnessApplier.hh | 61 +++++++++++++ ...hedRoughnessModel.cc => RoughnessModel.cc} | 45 ++++------ .../optical/surface/model/RoughnessModel.cu | 43 +++++++++ .../optical/surface/model/RoughnessModel.hh | 88 +++++++++++++++++++ .../surface/model/SmearRoughnessExecutor.hh | 53 +++-------- .../surface/model/SmearRoughnessModel.cc | 71 --------------- .../surface/model/SmearRoughnessModel.cu | 14 --- .../surface/model/SmearRoughnessModel.hh | 23 +++-- 31 files changed, 690 insertions(+), 254 deletions(-) create mode 100644 src/celeritas/optical/surface/TrackSlotExecutor.hh create mode 100644 src/celeritas/optical/surface/model/ControllerImpl.cc create mode 100644 src/celeritas/optical/surface/model/FakeExecutor.hh create mode 100644 src/celeritas/optical/surface/model/GaussianRoughnessExecutor.hh create mode 100644 src/celeritas/optical/surface/model/GaussianRoughnessModel.hh delete mode 100644 src/celeritas/optical/surface/model/PolishedRoughnessModel.cu create mode 100644 src/celeritas/optical/surface/model/RoughnessApplier.hh rename src/celeritas/optical/surface/model/{PolishedRoughnessModel.cc => RoughnessModel.cc} (57%) create mode 100644 src/celeritas/optical/surface/model/RoughnessModel.cu create mode 100644 src/celeritas/optical/surface/model/RoughnessModel.hh delete mode 100644 src/celeritas/optical/surface/model/SmearRoughnessModel.cc delete mode 100644 src/celeritas/optical/surface/model/SmearRoughnessModel.cu diff --git a/src/celeritas/CMakeLists.txt b/src/celeritas/CMakeLists.txt index ac6249cb7d..fd3f177f56 100644 --- a/src/celeritas/CMakeLists.txt +++ b/src/celeritas/CMakeLists.txt @@ -117,6 +117,7 @@ list(APPEND SOURCES optical/detail/OpticalLaunchAction.cc optical/surface/SurfacePhysicsParams.cc optical/surface/SurfaceSteppingAction.cc + optical/surface/model/ControllerImpl.cc phys/CutoffParams.cc phys/detail/EnergyMaxXsCalculator.cc phys/GeneratorInterface.cc @@ -363,9 +364,7 @@ celeritas_polysource(optical/gen/PrimaryGeneratorAction) celeritas_polysource(optical/gen/detail/GeneratorAlgorithms) celeritas_polysource(optical/gen/detail/OffloadAlgorithms) celeritas_polysource(optical/surface/BoundaryAction) -celeritas_polysource(optical/surface/model/GaussianRoughnessModel) -celeritas_polysource(optical/surface/model/PolishedRoughnessModel) -celeritas_polysource(optical/surface/model/SmearRoughnessModel) +celeritas_polysource(optical/surface/model/RoughnessModel) celeritas_polysource(phys/detail/DiscreteSelectAction) celeritas_polysource(phys/detail/PreStepAction) celeritas_polysource(phys/detail/TrackingCutAction) diff --git a/src/celeritas/optical/CoreParams.cc b/src/celeritas/optical/CoreParams.cc index d26e66fb1b..4122887587 100644 --- a/src/celeritas/optical/CoreParams.cc +++ b/src/celeritas/optical/CoreParams.cc @@ -112,6 +112,16 @@ CoreParams::CoreParams(Input&& input) : input_(std::move(input)) CELER_EXPECT(input_); + CELER_LOG_LOCAL(info) << " number of geometric surfaces: " + << input_.surface->num_surfaces(); + CELER_LOG_LOCAL(info) << " number of surfaces + default: " + << input_.surface_physics->num_surfaces(); + CELER_LOG_LOCAL(info) << " default surface: " + << input_.surface_physics->default_surface().get(); + + CELER_EXPECT(input_.surface->num_surfaces() + 1 + == input_.surface_physics->num_surfaces()); + // TODO: provide detectors in input, passing from core params detectors_ = input_.detectors; if (!detectors_) diff --git a/src/celeritas/optical/CoreTrackView.hh b/src/celeritas/optical/CoreTrackView.hh index 35a7ce5178..6910fc6e57 100644 --- a/src/celeritas/optical/CoreTrackView.hh +++ b/src/celeritas/optical/CoreTrackView.hh @@ -75,6 +75,10 @@ class CoreTrackView // Return a surface physics view inline CELER_FUNCTION SurfacePhysicsView surface_physics() const; + // Return a surface model view for the given step + inline CELER_FUNCTION + SurfaceModelView surface_model(SurfacePhysicsOrder) const; + // Return an RNG engine inline CELER_FUNCTION RngEngine rng() const; @@ -141,6 +145,9 @@ CoreTrackView::operator=(TrackInitializer const& init) // Initialize the physics state this->physics() = PhysicsTrackView::Initializer{}; + // Initialize the surface state + this->surface_physics().reset(); + return *this; } @@ -227,6 +234,21 @@ CELER_FUNCTION auto CoreTrackView::surface_physics() const -> SurfacePhysicsView this->track_slot_id()}; } +//---------------------------------------------------------------------------// +/*! + * Return a surface model view for the given step. + */ +CELER_FUNCTION auto CoreTrackView::surface_model(SurfacePhysicsOrder step) const + -> SurfaceModelView +{ + auto s_physics = this->surface_physics(); + CELER_EXPECT(s_physics.is_crossing_boundary()); + CELER_EXPECT(is_soft_unit_vector(this->geometry().dir())); + + return s_physics.surface_model( + s_physics.traversal_direction(this->geometry().dir()), step); +} + //---------------------------------------------------------------------------// /*! * Return the RNG engine. diff --git a/src/celeritas/optical/action/ActionLauncher.device.hh b/src/celeritas/optical/action/ActionLauncher.device.hh index d95c34a603..da184d875d 100644 --- a/src/celeritas/optical/action/ActionLauncher.device.hh +++ b/src/celeritas/optical/action/ActionLauncher.device.hh @@ -44,7 +44,7 @@ namespace optical } * \endcode */ -template +template class ActionLauncher : public KernelLauncher { static_assert( @@ -52,7 +52,7 @@ class ActionLauncher : public KernelLauncher || CELER_COMPILER == CELER_COMPILER_CLANG) && !std::is_pointer_v && !std::is_reference_v, R"(Launched action must be a trivially copyable function object)"); - using StepActionT = OpticalStepActionInterface; + // using StepActionT = OpticalStepActionInterface; public: // Create a launcher from a string @@ -76,8 +76,8 @@ class ActionLauncher : public KernelLauncher /*! * Create a launcher from an action. */ -template -ActionLauncher::ActionLauncher(StepActionT const& action) +template +ActionLauncher::ActionLauncher(StepActionT const& action) : ActionLauncher{action.label()} { } @@ -86,9 +86,9 @@ ActionLauncher::ActionLauncher(StepActionT const& action) /*! * Create a launcher with a string extension. */ -template -ActionLauncher::ActionLauncher(StepActionT const& action, - std::string_view ext) +template +ActionLauncher::ActionLauncher(StepActionT const& action, + std::string_view ext) : ActionLauncher{std::string(action.label()) + "-" + std::string(ext)} { } @@ -97,9 +97,9 @@ ActionLauncher::ActionLauncher(StepActionT const& action, /*! * Launch a kernel for the wrapped executor. */ -template -void ActionLauncher::operator()(CoreState const& state, - F const& call_thread) const +template +void ActionLauncher::operator()( + CoreState const& state, F const& call_thread) const { return (*this)( range(ThreadId{state.size()}), state.stream_id(), call_thread); diff --git a/src/celeritas/optical/action/detail/AlongStepExecutor.hh b/src/celeritas/optical/action/detail/AlongStepExecutor.hh index 77f42b39e1..a8f7da33ff 100644 --- a/src/celeritas/optical/action/detail/AlongStepExecutor.hh +++ b/src/celeritas/optical/action/detail/AlongStepExecutor.hh @@ -34,6 +34,11 @@ struct AlongStepExecutor //---------------------------------------------------------------------------// CELER_FUNCTION void AlongStepExecutor::operator()(CoreTrackView& track) { + if (track.surface_physics().is_crossing_boundary()) + { + return; + } + auto sim = track.sim(); CELER_ASSERT(sim.status() == TrackStatus::alive); diff --git a/src/celeritas/optical/action/detail/PreStepExecutor.hh b/src/celeritas/optical/action/detail/PreStepExecutor.hh index 7267409b77..5d5a1fb334 100644 --- a/src/celeritas/optical/action/detail/PreStepExecutor.hh +++ b/src/celeritas/optical/action/detail/PreStepExecutor.hh @@ -55,6 +55,11 @@ CELER_FUNCTION void PreStepExecutor::operator()(CoreTrackView const& track) || sim.status() == TrackStatus::alive); sim.status(TrackStatus::alive); + if (track.surface_physics().is_crossing_boundary()) + { + return; + } + auto phys = track.physics(); if (!phys.has_interaction_mfp()) { diff --git a/src/celeritas/optical/action/detail/PropagateExecutor.hh b/src/celeritas/optical/action/detail/PropagateExecutor.hh index 53119929e2..1004b9a2c8 100644 --- a/src/celeritas/optical/action/detail/PropagateExecutor.hh +++ b/src/celeritas/optical/action/detail/PropagateExecutor.hh @@ -32,6 +32,11 @@ struct PropagateExecutor //---------------------------------------------------------------------------// CELER_FUNCTION void PropagateExecutor::operator()(CoreTrackView& track) { + if (track.surface_physics().is_crossing_boundary()) + { + return; + } + auto&& sim = track.sim(); CELER_ASSERT(sim.status() == TrackStatus::alive); diff --git a/src/celeritas/optical/action/detail/TrackingCutExecutor.hh b/src/celeritas/optical/action/detail/TrackingCutExecutor.hh index b9f02baeef..a027f3e283 100644 --- a/src/celeritas/optical/action/detail/TrackingCutExecutor.hh +++ b/src/celeritas/optical/action/detail/TrackingCutExecutor.hh @@ -31,6 +31,11 @@ struct TrackingCutExecutor //---------------------------------------------------------------------------// CELER_FUNCTION void TrackingCutExecutor::operator()(CoreTrackView& track) { + if (track.surface_physics().is_crossing_boundary()) + { + return; + } + using Energy = ParticleTrackView::Energy; auto deposited = track.particle().energy().value(); diff --git a/src/celeritas/optical/surface/GaussianRoughnessSampler.hh b/src/celeritas/optical/surface/GaussianRoughnessSampler.hh index 2277101888..a3abdf110d 100644 --- a/src/celeritas/optical/surface/GaussianRoughnessSampler.hh +++ b/src/celeritas/optical/surface/GaussianRoughnessSampler.hh @@ -103,7 +103,9 @@ CELER_FUNCTION Real3 GaussianRoughnessSampler::operator()(Engine& rng) // nonpositive slope are generally vanishingly small) alpha = std::fabs(sample_alpha_(rng)); } while (alpha >= alpha_max_); - sincos(alpha, &sin_alpha, &cos_alpha); + sin_alpha = std::sin(alpha); + cos_alpha = std::cos(alpha); + // sincos(alpha, &sin_alpha, &cos_alpha); // Transform to polar angle using rejection } while (RejectionSampler{sin_alpha, f_max_}(rng)); diff --git a/src/celeritas/optical/surface/SurfaceModelView.hh b/src/celeritas/optical/surface/SurfaceModelView.hh index aceb368ab7..65c1f378c7 100644 --- a/src/celeritas/optical/surface/SurfaceModelView.hh +++ b/src/celeritas/optical/surface/SurfaceModelView.hh @@ -6,6 +6,9 @@ //---------------------------------------------------------------------------// #pragma once +#include "celeritas/optical/Types.hh" +#include "celeritas/phys/SurfacePhysicsMapView.hh" + namespace celeritas { namespace optical @@ -24,13 +27,25 @@ class SurfaceModelView public: //!@{ //! \name Type aliases + using InternalSurfaceId = SurfacePhysicsMapView::InternalSurfaceId; //!@} public: + inline CELER_FUNCTION + SurfaceModelView(SubsurfaceDirection, SurfacePhysicsMapView const&); + inline CELER_FUNCTION SubsurfaceDirection direction() const; - inline CELER_FUNCTION PhysSurfaceId phys_surface_id() const; + // inline CELER_FUNCTION PhysSurfaceId phys_surface_id() const; inline CELER_FUNCTION SurfaceModelId surface_model() const; inline CELER_FUNCTION InternalSurfaceId internal_surface_id() const; + inline CELER_FUNCTION OptMatId pre_material() const; + inline CELER_FUNCTION OptMatId post_material() const; + + private: + SubsurfaceDirection dir_; + SurfacePhysicsMapView physics_map_; + // OptMatId pre_material_; + // OptMatId post_material_; }; //---------------------------------------------------------------------------// @@ -38,6 +53,34 @@ class SurfaceModelView //---------------------------------------------------------------------------// /*! */ +CELER_FUNCTION +SurfaceModelView::SurfaceModelView(SubsurfaceDirection dir, + SurfacePhysicsMapView const& physics_map) + : dir_(dir), physics_map_(physics_map) +{ +} + +CELER_FUNCTION SubsurfaceDirection SurfaceModelView::direction() const +{ + return SubsurfaceDirection::forward; +} +CELER_FUNCTION SurfaceModelId SurfaceModelView::surface_model() const +{ + return {}; +} +CELER_FUNCTION auto SurfaceModelView::internal_surface_id() const + -> InternalSurfaceId +{ + return {}; +} +CELER_FUNCTION OptMatId SurfaceModelView::pre_material() const +{ + return {}; +} +CELER_FUNCTION OptMatId SurfaceModelView::post_material() const +{ + return {}; +} //---------------------------------------------------------------------------// } // namespace optical diff --git a/src/celeritas/optical/surface/SurfacePhysicsParams.cc b/src/celeritas/optical/surface/SurfacePhysicsParams.cc index d4a89a5264..56cfbdedc1 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsParams.cc +++ b/src/celeritas/optical/surface/SurfacePhysicsParams.cc @@ -11,6 +11,8 @@ #include "celeritas/inp/SurfacePhysics.hh" #include "celeritas/phys/SurfacePhysicsMapBuilder.hh" +#include "model/RoughnessModel.hh" + namespace celeritas { namespace optical @@ -30,25 +32,24 @@ class FakeModel : public SurfaceModel FakeModel(SurfaceModelId model_id, std::string_view label, std::map const& layer_map) - : SurfaceModel(model_id, label), layers_(layer_map) - { - } - - VecSurfaceLayer get_surfaces() const final + : SurfaceModel(model_id, label) { - VecSurfaceLayer result; - for ([[maybe_unused]] auto const& [layer, data] : layers_) + for (auto const& [layer, data] : layer_map) { - result.push_back(PhysSurfaceId(layer.get())); + CELER_ENSURE(layer); + surfaces_.push_back(layer); } - return result; + + CELER_ENSURE(layer_map.size() == surfaces_.size()); } + VecSurfaceLayer get_surfaces() const final { return surfaces_; } + void step(CoreParams const&, CoreStateHost&) const final {} void step(CoreParams const&, CoreStateDevice&) const final {} private: - std::map layers_; + std::vector surfaces_; }; //---------------------------------------------------------------------------// @@ -78,6 +79,17 @@ class FakeModelBuilder } } + template + void build(std::map const& layer_map) + { + if (!layer_map.empty()) + { + models_.push_back( + M::build_model(SurfaceModelId(models_.size()), layer_map)); + num_surf_ += layer_map.size(); + } + } + size_type num_surfaces() const { return num_surf_; } private: @@ -200,11 +212,13 @@ auto SurfacePhysicsParams::build_models( switch (step) { case SurfacePhysicsOrder::roughness: - build_model("polished", input.roughness.polished); - build_model("smear", input.roughness.smear); - build_model("gaussian", input.roughness.gaussian); + build_model.build( + input.roughness.polished); + build_model.build( + input.roughness.smear); + build_model.build( + input.roughness.gaussian); break; - case SurfacePhysicsOrder::reflectivity: build_model("grid", input.reflectivity.grid); build_model("fresnel", input.reflectivity.fresnel); diff --git a/src/celeritas/optical/surface/SurfacePhysicsParams.hh b/src/celeritas/optical/surface/SurfacePhysicsParams.hh index 89ad02233b..995565eb5f 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsParams.hh +++ b/src/celeritas/optical/surface/SurfacePhysicsParams.hh @@ -93,6 +93,18 @@ class SurfacePhysicsParams final return models_[step]; } + //! Number of geometric surfaces (including default surface) + SurfaceId::size_type num_surfaces() const + { + return data_.host_ref().surfaces.size(); + } + + //! Default surface ID + SurfaceId default_surface() const + { + return data_.host_ref().scalars.default_surface; + } + private: // Boundary actions std::shared_ptr init_boundary_action_; diff --git a/src/celeritas/optical/surface/SurfacePhysicsView.hh b/src/celeritas/optical/surface/SurfacePhysicsView.hh index 4ec789299b..932edfe147 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsView.hh +++ b/src/celeritas/optical/surface/SurfacePhysicsView.hh @@ -10,6 +10,7 @@ #include "celeritas/optical/Types.hh" #include "celeritas/phys/SurfacePhysicsMapView.hh" +#include "SurfaceModelView.hh" #include "SurfacePhysicsData.hh" #include "SurfacePhysicsUtils.hh" @@ -110,6 +111,11 @@ class SurfacePhysicsView SurfacePhysicsMapView surface_physics_map(SurfacePhysicsOrder, PhysSurfaceId) const; + // Get surface model for the given step + inline CELER_FUNCTION + SurfaceModelView surface_model(SubsurfaceDirection, + SurfacePhysicsOrder) const; + // Get local facet normal inline CELER_FUNCTION Real3 const& facet_normal() const; @@ -171,7 +177,7 @@ SurfacePhysicsView::SurfacePhysicsView(SurfaceParamsRef const& params, CELER_FUNCTION SurfacePhysicsView& SurfacePhysicsView::operator=(Initializer const& init) { - CELER_EXPECT(init.surface); + CELER_EXPECT(init.surface < params_.surfaces.size()); CELER_EXPECT(is_soft_unit_vector(init.global_normal)); states_.surface[track_id_] = init.surface; states_.surface_orientation[track_id_] = init.orientation; @@ -193,6 +199,7 @@ SurfacePhysicsView::operator=(Initializer const& init) CELER_FUNCTION void SurfacePhysicsView::reset() { states_.surface[track_id_] = {}; + CELER_ENSURE(!states_.surface[track_id_]); } //---------------------------------------------------------------------------// @@ -216,6 +223,7 @@ CELER_FUNCTION SurfaceId SurfacePhysicsView::surface() const */ CELER_FUNCTION SubsurfaceDirection SurfacePhysicsView::orientation() const { + CELER_EXPECT(this->is_crossing_boundary()); return states_.surface_orientation[track_id_]; } @@ -229,6 +237,7 @@ CELER_FUNCTION SubsurfaceDirection SurfacePhysicsView::orientation() const */ CELER_FUNCTION Real3 const& SurfacePhysicsView::global_normal() const { + CELER_EXPECT(this->is_crossing_boundary()); return states_.global_normal[track_id_]; } @@ -240,7 +249,7 @@ CELER_FUNCTION Real3 const& SurfacePhysicsView::global_normal() const */ CELER_FUNCTION bool SurfacePhysicsView::is_crossing_boundary() const { - return static_cast(this->surface()); + return this->surface() < params_.surfaces.size(); } //---------------------------------------------------------------------------// @@ -249,6 +258,7 @@ CELER_FUNCTION bool SurfacePhysicsView::is_crossing_boundary() const */ CELER_FUNCTION bool SurfacePhysicsView::is_exiting(SubsurfaceDirection d) const { + CELER_EXPECT(this->is_crossing_boundary()); // Use unsigned underflow when moving reverse (-1) on the pre-surface // (position 0) to wrap to an invalid position value return static_cast(this->subsurface_position().get() @@ -262,6 +272,7 @@ CELER_FUNCTION bool SurfacePhysicsView::is_exiting(SubsurfaceDirection d) const */ CELER_FUNCTION bool SurfacePhysicsView::in_pre_volume() const { + CELER_EXPECT(this->is_crossing_boundary()); return this->subsurface_position().get() == 0; } @@ -271,6 +282,7 @@ CELER_FUNCTION bool SurfacePhysicsView::in_pre_volume() const */ CELER_FUNCTION bool SurfacePhysicsView::in_post_volume() const { + CELER_EXPECT(this->is_crossing_boundary()); return this->subsurface_position().get() + 1 == this->num_positions(); } @@ -285,6 +297,7 @@ CELER_FUNCTION bool SurfacePhysicsView::in_post_volume() const */ CELER_FUNCTION SurfaceTrackPosition SurfacePhysicsView::subsurface_position() const { + CELER_EXPECT(this->is_crossing_boundary()); return states_.surface_position[track_id_]; } @@ -310,6 +323,7 @@ SurfacePhysicsView::subsurface_position(SurfaceTrackPosition pos) CELER_FUNCTION SurfaceTrackPosition::size_type SurfacePhysicsView::num_positions() const { + CELER_EXPECT(this->is_crossing_boundary()); return this->surface_record().subsurface_materials.size() + 2; } @@ -319,6 +333,8 @@ SurfacePhysicsView::num_positions() const */ CELER_FUNCTION OptMatId SurfacePhysicsView::subsurface_material() const { + CELER_EXPECT(this->is_crossing_boundary()); + if (this->in_pre_volume()) { return states_.pre_volume_material[track_id_]; @@ -345,6 +361,7 @@ CELER_FUNCTION OptMatId SurfacePhysicsView::subsurface_material() const CELER_FUNCTION PhysSurfaceId SurfacePhysicsView::subsurface_interface(SubsurfaceDirection d) const { + CELER_EXPECT(this->is_crossing_boundary()); CELER_EXPECT(!this->is_exiting(d)); auto track_pos = this->subsurface_position(); @@ -363,6 +380,7 @@ SurfacePhysicsView::subsurface_interface(SubsurfaceDirection d) const CELER_FUNCTION SubsurfaceDirection SurfacePhysicsView::traversal_direction(Real3 const& dir) const { + CELER_EXPECT(this->is_crossing_boundary()); CELER_EXPECT(is_soft_unit_vector(dir)); return static_cast( is_entering_surface(dir, this->global_normal())); @@ -375,15 +393,35 @@ SurfacePhysicsView::traversal_direction(Real3 const& dir) const CELER_FUNCTION SurfacePhysicsMapView SurfacePhysicsView::surface_physics_map( SurfacePhysicsOrder step, PhysSurfaceId surface) const { + CELER_EXPECT(this->is_crossing_boundary()); + CELER_EXPECT(surface); + CELER_EXPECT(step != SurfacePhysicsOrder::size_); + return SurfacePhysicsMapView{params_.model_maps[step], surface}; } +//---------------------------------------------------------------------------// +/*! + * Get surface model view of the given step in the given direction. + */ +CELER_FUNCTION SurfaceModelView SurfacePhysicsView::surface_model( + SubsurfaceDirection dir, SurfacePhysicsOrder step) const +{ + CELER_EXPECT(this->is_crossing_boundary()); + CELER_EXPECT(!this->is_exiting(dir)); + CELER_EXPECT(step != SurfacePhysicsOrder::size_); + + return SurfaceModelView{ + dir, this->surface_physics_map(step, this->subsurface_interface(dir))}; +} + //---------------------------------------------------------------------------// /*! * Get local facet normal after roughness sampling. */ CELER_FUNCTION Real3 const& SurfacePhysicsView::facet_normal() const { + CELER_EXPECT(this->is_crossing_boundary()); return states_.facet_normal[track_id_]; } @@ -393,6 +431,7 @@ CELER_FUNCTION Real3 const& SurfacePhysicsView::facet_normal() const */ CELER_FUNCTION void SurfacePhysicsView::facet_normal(Real3 const& normal) { + CELER_EXPECT(this->is_crossing_boundary()); CELER_EXPECT(is_soft_unit_vector(normal)); states_.facet_normal[track_id_] = normal; } @@ -404,6 +443,7 @@ CELER_FUNCTION void SurfacePhysicsView::facet_normal(Real3 const& normal) CELER_FUNCTION void SurfacePhysicsView::cross_subsurface_interface(SubsurfaceDirection d) { + CELER_EXPECT(this->is_crossing_boundary()); CELER_EXPECT(!this->is_exiting(d)); this->subsurface_position(this->subsurface_position() + to_signed_offset(d)); diff --git a/src/celeritas/optical/surface/TrackSlotExecutor.hh b/src/celeritas/optical/surface/TrackSlotExecutor.hh new file mode 100644 index 0000000000..94ac6e3548 --- /dev/null +++ b/src/celeritas/optical/surface/TrackSlotExecutor.hh @@ -0,0 +1,67 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/TrackSlotExecutor.hh +//---------------------------------------------------------------------------// +#pragma once + +#include "corecel/math/Algorithms.hh" +#include "celeritas/optical/action/TrackSlotExecutor.hh" + +#if !CELER_DEVICE_COMPILE +# include "corecel/io/Logger.hh" +#endif + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// + +struct IsSurfaceModelEqual +{ + SurfacePhysicsOrder step; + SurfaceModelId model; + + inline CELER_FUNCTION bool operator()(CoreTrackView const& track) const + { + if (!track.surface_physics().is_crossing_boundary()) + { + return false; + } + // #if !CELER_DEVICE_COMPILE + // if (!is_soft_unit_vector(track.geometry().dir())) + // { + // CELER_LOG_LOCAL(error) + // << " track surface: " + // << track.surface_physics().surface().unchecked_get() + // << " (invalid: " << SurfaceId{}.unchecked_get() + // << ", is_crossing_boundary: " + // << track.surface_physics().is_crossing_boundary() << + // ")"; + // } + // #endif + return track.surface_model(step).surface_model() == model; + } +}; + +template +inline CELER_FUNCTION decltype(auto) +make_surface_physics_executor(CoreParamsPtr params, + CoreStatePtr const& state, + SurfacePhysicsOrder step, + SurfaceModelId model, + T&& apply_track) +{ + CELER_EXPECT(step != SurfacePhysicsOrder::size_); + CELER_EXPECT(model); + return ConditionalTrackSlotExecutor{params, + state, + IsSurfaceModelEqual{step, model}, + celeritas::forward(apply_track)}; +} + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/VolumeSurfaceSelector.hh b/src/celeritas/optical/surface/VolumeSurfaceSelector.hh index 38a15e69d0..ec936dd687 100644 --- a/src/celeritas/optical/surface/VolumeSurfaceSelector.hh +++ b/src/celeritas/optical/surface/VolumeSurfaceSelector.hh @@ -107,7 +107,13 @@ VolumeSurfaceSelector::operator()(VolumeSurfaceView const& post_surface, // Return the L1 boundary surface from the opposite direction. // If no boundary surface exists, an invalid OrientedSurface is returned. - return {post_surface.boundary_id(), SubsurfaceDirection::reverse}; + + if (auto surface_id = post_surface.boundary_id()) + { + return {surface_id, SubsurfaceDirection::reverse}; + } + + return OrientedSurface{}; } //---------------------------------------------------------------------------// diff --git a/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh b/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh index 83ef20b7c7..3940c458f3 100644 --- a/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh +++ b/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh @@ -90,6 +90,18 @@ CELER_FUNCTION void InitBoundaryExecutor::operator()(CoreTrackView& track) const oriented_surface.orientation = SubsurfaceDirection::forward; } +#if !CELER_DEVICE_COMPILE + if (!is_soft_unit_vector(track.geometry().dir())) + { + CELER_LOG_LOCAL(error) + << " track surface: " + << track.surface_physics().surface().unchecked_get() + << " (invalid: " << SurfaceId{}.unchecked_get() + << ", is_crossing_boundary: " + << track.surface_physics().is_crossing_boundary() << ")"; + } +#endif + surface_physics = SurfacePhysicsView::Initializer{oriented_surface.surface, oriented_surface.orientation, diff --git a/src/celeritas/optical/surface/model/ControllerImpl.cc b/src/celeritas/optical/surface/model/ControllerImpl.cc new file mode 100644 index 0000000000..252e6887b7 --- /dev/null +++ b/src/celeritas/optical/surface/model/ControllerImpl.cc @@ -0,0 +1,47 @@ +#include "GaussianRoughnessModel.hh" +#include "PolishedRoughnessModel.hh" +#include "SmearRoughnessModel.hh" + +namespace celeritas +{ +namespace optical +{ + +GaussianRoughnessModelController::GaussianRoughnessModelController( + std::vector const& input) +{ + HostVal data; + auto build_sigma_alpha = ::celeritas::make_builder(&data.sigma_alpha); + + for (auto const& gaussian : input) + { + CELER_ENSURE(gaussian); + build_sigma_alpha.push_back(gaussian.sigma_alpha); + } + + CELER_ENSURE(data); + CELER_ENSURE(data.sigma_alpha.size() == input.size()); + + data_ = CollectionMirror{std::move(data)}; +} + +SmearRoughnessModelController::SmearRoughnessModelController( + std::vector const& input) +{ + HostVal data; + auto build_roughness = ::celeritas::make_builder(&data.roughness); + + for (auto const& smear : input) + { + CELER_ENSURE(smear); + build_roughness.push_back(smear.roughness); + } + + CELER_ENSURE(data); + CELER_ENSURE(data.roughness.size() == input.size()); + + data_ = CollectionMirror{std::move(data)}; +} + +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/FakeExecutor.hh b/src/celeritas/optical/surface/model/FakeExecutor.hh new file mode 100644 index 0000000000..dacbd0c3aa --- /dev/null +++ b/src/celeritas/optical/surface/model/FakeExecutor.hh @@ -0,0 +1,19 @@ +#pragma once + +#include "celeritas/optical/CoreTrackView.hh" + +namespace celeritas +{ +namespace optical +{ + +struct FakeExecutor +{ + CELER_FUNCTION void operator()(CoreTrackView& track) const + { + CELER_ASSERT(track.surface_physics().is_crossing_boundary()); + } +}; + +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/GaussianRoughnessExecutor.hh b/src/celeritas/optical/surface/model/GaussianRoughnessExecutor.hh new file mode 100644 index 0000000000..2d0177f672 --- /dev/null +++ b/src/celeritas/optical/surface/model/GaussianRoughnessExecutor.hh @@ -0,0 +1,40 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/GaussianRoughnessExecutor.hh +//---------------------------------------------------------------------------// +#pragma once + +#include "celeritas/optical/surface/GaussianRoughnessSampler.hh" +#include "celeritas/optical/surface/SurfaceModelView.hh" +#include "celeritas/optical/surface/SurfacePhysicsUtils.hh" + +#include "GaussianRoughnessData.hh" + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// +struct GaussianRoughnessExecutorBuilder +{ + //!@{ + //! \name Type aliases + using Sampler = EnteringSurfaceNormalSampler; + //!@} + + NativeCRef data; + + CELER_FUNCTION Sampler operator()(SurfaceModelView const& model, + Real3 const& dir, + Real3 const& normal) const + { + return Sampler( + dir, normal, data.sigma_alpha[model.internal_surface_id()]); + } +}; + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh b/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh new file mode 100644 index 0000000000..658de0f83f --- /dev/null +++ b/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh @@ -0,0 +1,43 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/GaussianRoughnessModel.hh +//---------------------------------------------------------------------------// +#pragma once + +#include "corecel/data/CollectionBuilder.hh" +#include "corecel/data/CollectionMirror.hh" +#include "celeritas/inp/SurfacePhysics.hh" + +#include "GaussianRoughnessData.hh" +#include "GaussianRoughnessExecutor.hh" + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// +/*! + */ +class GaussianRoughnessModelController +{ + public: + constexpr static std::string_view label = "gaussian"; + + GaussianRoughnessModelController( + std::vector const& input); + + template + GaussianRoughnessExecutorBuilder make_builder() const + { + return GaussianRoughnessExecutorBuilder{data_.ref()}; + } + + private: + CollectionMirror data_; +}; + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessExecutor.hh b/src/celeritas/optical/surface/model/PolishedRoughnessExecutor.hh index 9cd5b34b3b..ca761b825b 100644 --- a/src/celeritas/optical/surface/model/PolishedRoughnessExecutor.hh +++ b/src/celeritas/optical/surface/model/PolishedRoughnessExecutor.hh @@ -6,9 +6,7 @@ //---------------------------------------------------------------------------// #pragma once -#include "corecel/math/ArrayOperators.hh" -#include "celeritas/optical/CoreTrackView.hh" -#include "celeritas/optical/surface/SurfacePhysicsUtils.hh" +#include "celeritas/Types.hh" namespace celeritas { @@ -16,39 +14,26 @@ namespace optical { //---------------------------------------------------------------------------// /*! - * Brief class description. - * - * Optional detailed class description, and possibly example usage: - * \code - PolishedRoughnessExecutor ...; - \endcode */ struct PolishedRoughnessExecutor { - inline CELER_FUNCTION void operator()(CoreTrackView& track) const; + Real3 const& normal; + + template + CELER_FUNCTION Real3 operator()(Engine&) const + { + return normal; + } }; -//---------------------------------------------------------------------------// -// INLINE DEFINITIONS -//---------------------------------------------------------------------------// -/*! - */ -CELER_FUNCTION void -PolishedRoughnessExecutor::operator()(CoreTrackView& track) const +struct PolishedRoughnessExecutorBuilder { - auto s_physics = track.surface_physics(); - - auto dir = s_physics.traversal_direction(track.geometry().dir()); - CELER_ASSERT(!s_physics.is_exiting(dir)); - - Real3 normal = s_physics.global_normal(); - if (dir == SubsurfaceDirection::reverse) + CELER_FUNCTION PolishedRoughnessExecutor operator()( + SurfaceModelView const&, Real3 const&, Real3 const& normal) const { - normal = -normal; + return PolishedRoughnessExecutor{normal}; } - - s_physics.facet_normal(normal); -} +}; //---------------------------------------------------------------------------// } // namespace optical diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cu b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cu deleted file mode 100644 index 1e5f4aa678..0000000000 --- a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cu +++ /dev/null @@ -1,14 +0,0 @@ -//------------------------------ -*- cuda -*- -------------------------------// -// Copyright Celeritas contributors: see top-level COPYRIGHT file for details -// SPDX-License-Identifier: (Apache-2.0 OR MIT) -//---------------------------------------------------------------------------// -//! \file celeritas/optical/surface/model/PolishedRoughnessModel.cu -//---------------------------------------------------------------------------// -#include "PolishedRoughnessModel.hh" - -namespace celeritas -{ -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// -} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh b/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh index a3c6f8895e..fc059a6cac 100644 --- a/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh +++ b/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh @@ -6,12 +6,17 @@ //---------------------------------------------------------------------------// #pragma once -#include "corecel/data/CollectionMirror.hh" -#include "celeritas/inp/SurfacePhysics.hh" -#include "celeritas/optical/surface/SurfaceModel.hh" +#include +#include + +#include "PolishedRoughnessExecutor.hh" namespace celeritas { +namespace inp +{ +struct NoRoughness; +} namespace optical { //---------------------------------------------------------------------------// @@ -23,22 +28,18 @@ namespace optical PolishedRoughnessModel ...; \endcode */ -class PolishedRoughnessModel : public SurfaceModel +class PolishedRoughnessModelController { public: - //!@{ - //! \name Type aliases - //!@} + constexpr static std::string_view label = "polished"; - public: - PolishedRoughnessModel(SurfaceModelId, - std::map const&); - std::vector get_surfaces() const final; - void step(CoreParams const&, CoreStateHost&) const final; - void step(CoreParams const&, CoreStateDevice&) const final; + PolishedRoughnessModelController(std::vector const&) {} - private: - std::vector surfaces_; + template + PolishedRoughnessExecutorBuilder make_builder() const + { + return PolishedRoughnessExecutorBuilder{}; + } }; //---------------------------------------------------------------------------// diff --git a/src/celeritas/optical/surface/model/RoughnessApplier.hh b/src/celeritas/optical/surface/model/RoughnessApplier.hh new file mode 100644 index 0000000000..6583d62b3f --- /dev/null +++ b/src/celeritas/optical/surface/model/RoughnessApplier.hh @@ -0,0 +1,61 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/RoughnessApplier.hh +//---------------------------------------------------------------------------// +#pragma once + +#include "corecel/math/ArrayOperators.hh" +#include "celeritas/optical/CoreTrackView.hh" + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// +/*! + */ +template +class RoughnessApplier +{ + public: + CELER_FUNCTION RoughnessApplier(T&& executor_builder) + : executor_builder_{celeritas::forward(executor_builder)} + { + } + + inline CELER_FUNCTION void operator()(CoreTrackView& track) const; + + private: + T executor_builder_; +}; + +// template CELER_FUNCTION RoughnessApplier( + +//---------------------------------------------------------------------------// +// INLINE DEFINITIONS +//---------------------------------------------------------------------------// +/*! + */ +template +CELER_FUNCTION void RoughnessApplier::operator()(CoreTrackView& track) const +{ + auto s_physics = track.surface_physics(); + auto model_view = track.surface_model(SurfacePhysicsOrder::roughness); + auto rng = track.rng(); + + auto normal = s_physics.global_normal(); + if (model_view.direction() == SubsurfaceDirection::reverse) + { + normal = -normal; + } + + auto sample = executor_builder_(model_view, track.geometry().dir(), normal); + + s_physics.facet_normal(sample(rng)); +} + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc b/src/celeritas/optical/surface/model/RoughnessModel.cc similarity index 57% rename from src/celeritas/optical/surface/model/PolishedRoughnessModel.cc rename to src/celeritas/optical/surface/model/RoughnessModel.cc index 32266924f4..17f0c354f8 100644 --- a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc +++ b/src/celeritas/optical/surface/model/RoughnessModel.cc @@ -2,58 +2,47 @@ // Copyright Celeritas contributors: see top-level COPYRIGHT file for details // SPDX-License-Identifier: (Apache-2.0 OR MIT) //---------------------------------------------------------------------------// -//! \file celeritas/optical/surface/model/PolishedRoughnessModel.cc +//! \file celeritas/optical/surface/model/RoughnessModel.cc //---------------------------------------------------------------------------// -#include "PolishedRoughnessModel.hh" +#include "RoughnessModel.hh" -#include "corecel/data/CollectionBuilder.hh" #include "celeritas/optical/CoreParams.hh" #include "celeritas/optical/CoreState.hh" #include "celeritas/optical/action/ActionLauncher.hh" #include "celeritas/optical/surface/TrackSlotExecutor.hh" -#include "PolishedRoughnessExecutor.hh" +#include "FakeExecutor.hh" namespace celeritas { namespace optical { //---------------------------------------------------------------------------// -/*! - * - */ -PolishedRoughnessModel::PolishedRoughnessModel( - SurfaceModelId model, - std::map const& layer_map) - : SurfaceModel(model, "polished") -{ - for (auto const& [surface, polished] : layer_map) - { - CELER_EXPECT(surface); - surfaces_.push_back(surface); - } -} - -std::vector PolishedRoughnessModel::get_surfaces() const -{ - return surfaces_; -} - -void PolishedRoughnessModel::step(CoreParams const& params, - CoreStateHost& state) const +template +void RoughnessModel::step(CoreParams const& params, + CoreStateHost& state) const { launch_action(state, make_surface_physics_executor(params.ptr(), state.ptr(), SurfacePhysicsOrder::roughness, this->surface_model_id(), - PolishedRoughnessExecutor{})); + FakeExecutor{})); + // RoughnessApplier{ + // controller_.template make_builder()})); } -void PolishedRoughnessModel::step(CoreParams const&, CoreStateDevice&) const +#if !CELER_USE_DEVICE +template +void RoughnessModel::step(CoreParams const&, CoreStateDevice&) const { CELER_NOT_IMPLEMENTED("CUDA OR HIP"); } +#endif + +template class RoughnessModel; +template class RoughnessModel; +template class RoughnessModel; //---------------------------------------------------------------------------// } // namespace optical diff --git a/src/celeritas/optical/surface/model/RoughnessModel.cu b/src/celeritas/optical/surface/model/RoughnessModel.cu new file mode 100644 index 0000000000..5568eb0809 --- /dev/null +++ b/src/celeritas/optical/surface/model/RoughnessModel.cu @@ -0,0 +1,43 @@ +//------------------------------ -*- cuda -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/RoughnessModel.cu +//---------------------------------------------------------------------------// +#include "RoughnessModel.hh" + +#include "celeritas/optical/CoreParams.hh" +#include "celeritas/optical/CoreState.hh" +#include "celeritas/optical/action/ActionLauncher.device.hh" +#include "celeritas/optical/surface/TrackSlotExecutor.hh" + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// +template +void RoughnessModel::step(CoreParams const& /* params */, + CoreStateDevice& /* state */) const +{ + /* + auto execute = make_surface_physics_executor( + params.ptr(), + state.ptr(), + SurfacePhysicsOrder::roughness, + this->surface_model_id(), + RoughnessApplier{ + controller_.template make_builder()}); + + static ActionLauncher const + launch_kernel(*this); launch_kernel(state, execute); + */ +} + +template class RoughnessModel; +template class RoughnessModel; +template class RoughnessModel; + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/RoughnessModel.hh b/src/celeritas/optical/surface/model/RoughnessModel.hh new file mode 100644 index 0000000000..7769b917ef --- /dev/null +++ b/src/celeritas/optical/surface/model/RoughnessModel.hh @@ -0,0 +1,88 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/RoughnessModel.hh +//---------------------------------------------------------------------------// +#pragma once + +#include "celeritas/optical/surface/SurfaceModel.hh" + +#include "GaussianRoughnessModel.hh" +#include "PolishedRoughnessModel.hh" +#include "RoughnessApplier.hh" +#include "SmearRoughnessModel.hh" + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// +/*! + * Brief class description. + * + * Optional detailed class description, and possibly example usage: + * \code + RoughnessModel ...; + \endcode + */ +template +class RoughnessModel : public SurfaceModel +{ + public: + template + static std::shared_ptr> + build_model(SurfaceModelId model_id, + std::map const& layer_map) + { + std::vector surfaces; + std::vector inputs; + + for (auto const& [surface, input] : layer_map) + { + CELER_ENSURE(surface); + surfaces.push_back(surface); + inputs.push_back(input); + } + + CELER_ENSURE(surfaces.size() == layer_map.size()); + CELER_ENSURE(inputs.size() == layer_map.size()); + + return std::make_shared(model_id, + Controller::label, + std::move(surfaces), + Controller{inputs}); + } + + std::vector get_surfaces() const final { return surfaces_; } + + void step(CoreParams const& params, CoreStateHost& state) const final; + + void step(CoreParams const&, CoreStateDevice&) const final; + + RoughnessModel(SurfaceModelId model_id, + std::string_view label, + std::vector surfaces, + Controller controller) + : SurfaceModel(model_id, label) + , controller_(std::move(controller)) + , surfaces_(std::move(surfaces)) + { + } + + protected: + Controller controller_; + std::vector surfaces_; +}; + +extern template class RoughnessModel; +extern template class RoughnessModel; +extern template class RoughnessModel; + +using SmearRoughnessModel = RoughnessModel; +using PolishedRoughnessModel = RoughnessModel; +using GaussianRoughnessModel = RoughnessModel; + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/SmearRoughnessExecutor.hh b/src/celeritas/optical/surface/model/SmearRoughnessExecutor.hh index 0ff47bd7bb..9177bdeb1c 100644 --- a/src/celeritas/optical/surface/model/SmearRoughnessExecutor.hh +++ b/src/celeritas/optical/surface/model/SmearRoughnessExecutor.hh @@ -6,9 +6,8 @@ //---------------------------------------------------------------------------// #pragma once -#include "corecel/math/ArrayOperators.hh" -#include "celeritas/optical/CoreTrackView.hh" #include "celeritas/optical/surface/SmearRoughnessSampler.hh" +#include "celeritas/optical/surface/SurfaceModelView.hh" #include "celeritas/optical/surface/SurfacePhysicsUtils.hh" #include "SmearRoughnessData.hh" @@ -17,53 +16,27 @@ namespace celeritas { namespace optical { -//---------------------------------------------------------------------------// -/*! - * Brief class description. - * - * Optional detailed class description, and possibly example usage: - * \code - SmearRoughnessExecutor ...; - \endcode - */ -struct SmearRoughnessExecutor -{ - NativeCRef data; - - inline CELER_FUNCTION void operator()(CoreTrackView& track) const; -}; -//---------------------------------------------------------------------------// -// INLINE DEFINITIONS //---------------------------------------------------------------------------// /*! */ -CELER_FUNCTION void -SmearRoughnessExecutor::operator()(CoreTrackView& track) const +struct SmearRoughnessExecutorBuilder { - auto s_physics = track.surface_physics(); + //!@{ + //! \name Type aliases + using Sampler = EnteringSurfaceNormalSampler; + //!@} - auto dir = s_physics.traversal_direction(track.geometry().dir()); - CELER_ASSERT(!s_physics.is_exiting(dir)); + NativeCRef data; - Real3 normal = s_physics.global_normal(); - if (dir == SubsurfaceDirection::reverse) + CELER_FUNCTION Sampler operator()(SurfaceModelView const& model, + Real3 const& dir, + Real3 const& normal) const { - normal = -normal; + return Sampler( + dir, normal, data.roughness[model.internal_surface_id()]); } - - auto rng = track.rng(); - - auto phys_surface_id = s_physics.subsurface_interface(dir); - auto facet_normal = SmearRoughnessSampler{ - normal, - data.roughness[s_physics - .surface_physics_map(SurfacePhysicsOrder::roughness, - phys_surface_id) - .internal_surface_id()]}(rng); - - s_physics.facet_normal(facet_normal); -} +}; //---------------------------------------------------------------------------// } // namespace optical diff --git a/src/celeritas/optical/surface/model/SmearRoughnessModel.cc b/src/celeritas/optical/surface/model/SmearRoughnessModel.cc deleted file mode 100644 index 4487454e2f..0000000000 --- a/src/celeritas/optical/surface/model/SmearRoughnessModel.cc +++ /dev/null @@ -1,71 +0,0 @@ -//------------------------------- -*- C++ -*- -------------------------------// -// Copyright Celeritas contributors: see top-level COPYRIGHT file for details -// SPDX-License-Identifier: (Apache-2.0 OR MIT) -//---------------------------------------------------------------------------// -//! \file celeritas/optical/surface/model/SmearRoughnessModel.cc -//---------------------------------------------------------------------------// -#include "SmearRoughnessModel.hh" - -#include "corecel/data/CollectionBuilder.hh" -#include "celeritas/optical/CoreParams.hh" -#include "celeritas/optical/CoreState.hh" -#include "celeritas/optical/action/ActionLauncher.hh" -#include "celeritas/optical/surface/TrackSlotExecutor.hh" - -#include "SmearRoughnessExecutor.hh" - -namespace celeritas -{ -namespace optical -{ -//---------------------------------------------------------------------------// -/*! - */ -SmearRoughnessModel::SmearRoughnessModel( - SurfaceModelId model, - std::map const& layer_map) - : SurfaceModel(model, "smear") -{ - HostVal data; - - auto build_roughness = make_builder(&data.roughness); - - for (auto const& [surface, smear] : layer_map) - { - CELER_EXPECT(surface); - surfaces_.push_back(surface); - - CELER_EXPECT(smear); - build_roughness.push_back(smear.roughness); - } - - CELER_ENSURE(data); - - data_ = CollectionMirror{std::move(data)}; -} - -std::vector SmearRoughnessModel::get_surfaces() const -{ - return surfaces_; -} - -void SmearRoughnessModel::step(CoreParams const& params, - CoreStateHost& state) const -{ - launch_action(state, - make_surface_physics_executor( - params.ptr(), - state.ptr(), - SurfacePhysicsOrder::roughness, - this->surface_model_id(), - SmearRoughnessExecutor{data_.host_ref()})); -} - -void SmearRoughnessModel::step(CoreParams const&, CoreStateDevice&) const -{ - CELER_NOT_IMPLEMENTED("CUDA OR HIP"); -} - -//---------------------------------------------------------------------------// -} // namespace optical -} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/SmearRoughnessModel.cu b/src/celeritas/optical/surface/model/SmearRoughnessModel.cu deleted file mode 100644 index 5dd49b7c12..0000000000 --- a/src/celeritas/optical/surface/model/SmearRoughnessModel.cu +++ /dev/null @@ -1,14 +0,0 @@ -//------------------------------ -*- cuda -*- -------------------------------// -// Copyright Celeritas contributors: see top-level COPYRIGHT file for details -// SPDX-License-Identifier: (Apache-2.0 OR MIT) -//---------------------------------------------------------------------------// -//! \file celeritas/optical/surface/model/SmearRoughnessModel.cu -//---------------------------------------------------------------------------// -#include "SmearRoughnessModel.hh" - -namespace celeritas -{ -//---------------------------------------------------------------------------// - -//---------------------------------------------------------------------------// -} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/SmearRoughnessModel.hh b/src/celeritas/optical/surface/model/SmearRoughnessModel.hh index d3c8a005d2..467cbfc7cc 100644 --- a/src/celeritas/optical/surface/model/SmearRoughnessModel.hh +++ b/src/celeritas/optical/surface/model/SmearRoughnessModel.hh @@ -6,11 +6,12 @@ //---------------------------------------------------------------------------// #pragma once +#include "corecel/data/CollectionBuilder.hh" #include "corecel/data/CollectionMirror.hh" #include "celeritas/inp/SurfacePhysics.hh" -#include "celeritas/optical/surface/SurfaceModel.hh" #include "SmearRoughnessData.hh" +#include "SmearRoughnessExecutor.hh" namespace celeritas { @@ -25,22 +26,20 @@ namespace optical SmearRoughnessModel ...; \endcode */ -class SmearRoughnessModel : public SurfaceModel +class SmearRoughnessModelController { public: - //!@{ - //! \name Type aliases - //!@} + constexpr static std::string_view label = "smear"; - public: - SmearRoughnessModel(SurfaceModelId, - std::map const&); - std::vector get_surfaces() const final; - void step(CoreParams const&, CoreStateHost&) const final; - void step(CoreParams const&, CoreStateDevice&) const final; + SmearRoughnessModelController(std::vector const& input); + + template + SmearRoughnessExecutorBuilder make_builder() const + { + return SmearRoughnessExecutorBuilder{data_.ref()}; + } private: - std::vector surfaces_; CollectionMirror data_; }; From 0335b15d5416c1b44b82b4a6e0f02566a66f86f1 Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Fri, 29 Aug 2025 16:20:11 -0500 Subject: [PATCH 06/22] Refactor RoughnessModel --- src/celeritas/CMakeLists.txt | 5 +- .../optical/surface/SurfacePhysicsParams.cc | 19 +++--- .../optical/surface/TrackSlotExecutor.hh | 23 +------ .../optical/surface/VolumeSurfaceSelector.hh | 8 +-- .../optical/surface/model/ControllerImpl.cc | 47 -------------- .../optical/surface/model/FakeExecutor.hh | 19 ------ .../surface/model/GaussianRoughnessModel.cc | 62 +++++++++++++++++++ .../surface/model/GaussianRoughnessModel.cu | 34 ++++++++++ .../surface/model/GaussianRoughnessModel.hh | 24 +++---- .../surface/model/PolishedRoughnessModel.cc | 48 ++++++++++++++ .../surface/model/PolishedRoughnessModel.cu | 34 ++++++++++ .../surface/model/PolishedRoughnessModel.hh | 26 +++----- .../optical/surface/model/RoughnessModel.cc | 49 --------------- .../optical/surface/model/RoughnessModel.hh | 62 +++++++------------ .../surface/model/SmearRoughnessModel.cc | 61 ++++++++++++++++++ ...ughnessModel.cu => SmearRoughnessModel.cu} | 31 ++++------ .../surface/model/SmearRoughnessModel.hh | 29 ++++----- 17 files changed, 321 insertions(+), 260 deletions(-) delete mode 100644 src/celeritas/optical/surface/model/ControllerImpl.cc delete mode 100644 src/celeritas/optical/surface/model/FakeExecutor.hh create mode 100644 src/celeritas/optical/surface/model/GaussianRoughnessModel.cc create mode 100644 src/celeritas/optical/surface/model/GaussianRoughnessModel.cu create mode 100644 src/celeritas/optical/surface/model/PolishedRoughnessModel.cc create mode 100644 src/celeritas/optical/surface/model/PolishedRoughnessModel.cu delete mode 100644 src/celeritas/optical/surface/model/RoughnessModel.cc create mode 100644 src/celeritas/optical/surface/model/SmearRoughnessModel.cc rename src/celeritas/optical/surface/model/{RoughnessModel.cu => SmearRoughnessModel.cu} (52%) diff --git a/src/celeritas/CMakeLists.txt b/src/celeritas/CMakeLists.txt index fd3f177f56..ac6249cb7d 100644 --- a/src/celeritas/CMakeLists.txt +++ b/src/celeritas/CMakeLists.txt @@ -117,7 +117,6 @@ list(APPEND SOURCES optical/detail/OpticalLaunchAction.cc optical/surface/SurfacePhysicsParams.cc optical/surface/SurfaceSteppingAction.cc - optical/surface/model/ControllerImpl.cc phys/CutoffParams.cc phys/detail/EnergyMaxXsCalculator.cc phys/GeneratorInterface.cc @@ -364,7 +363,9 @@ celeritas_polysource(optical/gen/PrimaryGeneratorAction) celeritas_polysource(optical/gen/detail/GeneratorAlgorithms) celeritas_polysource(optical/gen/detail/OffloadAlgorithms) celeritas_polysource(optical/surface/BoundaryAction) -celeritas_polysource(optical/surface/model/RoughnessModel) +celeritas_polysource(optical/surface/model/GaussianRoughnessModel) +celeritas_polysource(optical/surface/model/PolishedRoughnessModel) +celeritas_polysource(optical/surface/model/SmearRoughnessModel) celeritas_polysource(phys/detail/DiscreteSelectAction) celeritas_polysource(phys/detail/PreStepAction) celeritas_polysource(phys/detail/TrackingCutAction) diff --git a/src/celeritas/optical/surface/SurfacePhysicsParams.cc b/src/celeritas/optical/surface/SurfacePhysicsParams.cc index 56cfbdedc1..ecbd12b644 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsParams.cc +++ b/src/celeritas/optical/surface/SurfacePhysicsParams.cc @@ -11,7 +11,9 @@ #include "celeritas/inp/SurfacePhysics.hh" #include "celeritas/phys/SurfacePhysicsMapBuilder.hh" -#include "model/RoughnessModel.hh" +#include "model/GaussianRoughnessModel.hh" +#include "model/PolishedRoughnessModel.hh" +#include "model/SmearRoughnessModel.hh" namespace celeritas { @@ -79,13 +81,13 @@ class FakeModelBuilder } } - template - void build(std::map const& layer_map) + template + void build(std::map const& layer_map) { if (!layer_map.empty()) { - models_.push_back( - M::build_model(SurfaceModelId(models_.size()), layer_map)); + models_.push_back(RoughnessModel::from_input( + SurfaceModelId(models_.size()), layer_map)); num_surf_ += layer_map.size(); } } @@ -212,11 +214,10 @@ auto SurfacePhysicsParams::build_models( switch (step) { case SurfacePhysicsOrder::roughness: - build_model.build( + build_model.build( input.roughness.polished); - build_model.build( - input.roughness.smear); - build_model.build( + build_model.build(input.roughness.smear); + build_model.build( input.roughness.gaussian); break; case SurfacePhysicsOrder::reflectivity: diff --git a/src/celeritas/optical/surface/TrackSlotExecutor.hh b/src/celeritas/optical/surface/TrackSlotExecutor.hh index 94ac6e3548..7c369827e9 100644 --- a/src/celeritas/optical/surface/TrackSlotExecutor.hh +++ b/src/celeritas/optical/surface/TrackSlotExecutor.hh @@ -9,10 +9,6 @@ #include "corecel/math/Algorithms.hh" #include "celeritas/optical/action/TrackSlotExecutor.hh" -#if !CELER_DEVICE_COMPILE -# include "corecel/io/Logger.hh" -#endif - namespace celeritas { namespace optical @@ -26,23 +22,8 @@ struct IsSurfaceModelEqual inline CELER_FUNCTION bool operator()(CoreTrackView const& track) const { - if (!track.surface_physics().is_crossing_boundary()) - { - return false; - } - // #if !CELER_DEVICE_COMPILE - // if (!is_soft_unit_vector(track.geometry().dir())) - // { - // CELER_LOG_LOCAL(error) - // << " track surface: " - // << track.surface_physics().surface().unchecked_get() - // << " (invalid: " << SurfaceId{}.unchecked_get() - // << ", is_crossing_boundary: " - // << track.surface_physics().is_crossing_boundary() << - // ")"; - // } - // #endif - return track.surface_model(step).surface_model() == model; + return track.surface_physics().is_crossing_boundary() + && track.surface_model(step).surface_model() == model; } }; diff --git a/src/celeritas/optical/surface/VolumeSurfaceSelector.hh b/src/celeritas/optical/surface/VolumeSurfaceSelector.hh index ec936dd687..38a15e69d0 100644 --- a/src/celeritas/optical/surface/VolumeSurfaceSelector.hh +++ b/src/celeritas/optical/surface/VolumeSurfaceSelector.hh @@ -107,13 +107,7 @@ VolumeSurfaceSelector::operator()(VolumeSurfaceView const& post_surface, // Return the L1 boundary surface from the opposite direction. // If no boundary surface exists, an invalid OrientedSurface is returned. - - if (auto surface_id = post_surface.boundary_id()) - { - return {surface_id, SubsurfaceDirection::reverse}; - } - - return OrientedSurface{}; + return {post_surface.boundary_id(), SubsurfaceDirection::reverse}; } //---------------------------------------------------------------------------// diff --git a/src/celeritas/optical/surface/model/ControllerImpl.cc b/src/celeritas/optical/surface/model/ControllerImpl.cc deleted file mode 100644 index 252e6887b7..0000000000 --- a/src/celeritas/optical/surface/model/ControllerImpl.cc +++ /dev/null @@ -1,47 +0,0 @@ -#include "GaussianRoughnessModel.hh" -#include "PolishedRoughnessModel.hh" -#include "SmearRoughnessModel.hh" - -namespace celeritas -{ -namespace optical -{ - -GaussianRoughnessModelController::GaussianRoughnessModelController( - std::vector const& input) -{ - HostVal data; - auto build_sigma_alpha = ::celeritas::make_builder(&data.sigma_alpha); - - for (auto const& gaussian : input) - { - CELER_ENSURE(gaussian); - build_sigma_alpha.push_back(gaussian.sigma_alpha); - } - - CELER_ENSURE(data); - CELER_ENSURE(data.sigma_alpha.size() == input.size()); - - data_ = CollectionMirror{std::move(data)}; -} - -SmearRoughnessModelController::SmearRoughnessModelController( - std::vector const& input) -{ - HostVal data; - auto build_roughness = ::celeritas::make_builder(&data.roughness); - - for (auto const& smear : input) - { - CELER_ENSURE(smear); - build_roughness.push_back(smear.roughness); - } - - CELER_ENSURE(data); - CELER_ENSURE(data.roughness.size() == input.size()); - - data_ = CollectionMirror{std::move(data)}; -} - -} // namespace optical -} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/FakeExecutor.hh b/src/celeritas/optical/surface/model/FakeExecutor.hh deleted file mode 100644 index dacbd0c3aa..0000000000 --- a/src/celeritas/optical/surface/model/FakeExecutor.hh +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "celeritas/optical/CoreTrackView.hh" - -namespace celeritas -{ -namespace optical -{ - -struct FakeExecutor -{ - CELER_FUNCTION void operator()(CoreTrackView& track) const - { - CELER_ASSERT(track.surface_physics().is_crossing_boundary()); - } -}; - -} // namespace optical -} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc b/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc new file mode 100644 index 0000000000..2d0f843062 --- /dev/null +++ b/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc @@ -0,0 +1,62 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/GaussianRoughnessModel.cc +//---------------------------------------------------------------------------// +#include "GaussianRoughnessModel.hh" + +#include "corecel/data/CollectionBuilder.hh" +#include "celeritas/inp/SurfacePhysics.hh" +#include "celeritas/optical/CoreParams.hh" +#include "celeritas/optical/CoreState.hh" +#include "celeritas/optical/action/ActionLauncher.hh" +#include "celeritas/optical/surface/TrackSlotExecutor.hh" + +#include "GaussianRoughnessExecutor.hh" + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// +GaussianRoughnessModel::GaussianRoughnessModel( + SurfaceModelId model, + std::vector surfaces, + std::vector const& inputs) + : RoughnessModel(model, "gaussian", std::move(surfaces)) +{ + HostVal data; + auto build_sigma_alpha = ::celeritas::make_builder(&data.sigma_alpha); + + for (auto const& gaussian : inputs) + { + CELER_ENSURE(gaussian); + build_sigma_alpha.push_back(gaussian.sigma_alpha); + } + + CELER_ENSURE(data); + CELER_ENSURE(data.sigma_alpha.size() == inputs.size()); + + data_ = CollectionMirror{std::move(data)}; +} + +void GaussianRoughnessModel::step(CoreParams const& params, + CoreStateHost& state) const +{ + launch_action( + state, + this->make_executor( + params, state, GaussianRoughnessExecutorBuilder{data_.host_ref()})); +} + +#if !CELER_USE_DEVICE +void GaussianRoughnessModel::step(CoreParams const&, CoreStateDevice&) const +{ + CELER_NOT_IMPLEMENTED("CUDA OR HIP"); +} +#endif + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/GaussianRoughnessModel.cu b/src/celeritas/optical/surface/model/GaussianRoughnessModel.cu new file mode 100644 index 0000000000..eb560afef9 --- /dev/null +++ b/src/celeritas/optical/surface/model/GaussianRoughnessModel.cu @@ -0,0 +1,34 @@ +//------------------------------ -*- cuda -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/GaussianRoughnessModel.cu +//---------------------------------------------------------------------------// +#include "GaussianRoughnessModel.hh" + +#include "celeritas/optical/CoreParams.hh" +#include "celeritas/optical/CoreState.hh" +#include "celeritas/optical/action/ActionLauncher.device.hh" +#include "celeritas/optical/surface/TrackSlotExecutor.hh" + +#include "GaussianRoughnessExecutor.hh" + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// +void GaussianRoughnessModel::step(CoreParams const& params, + CoreStateDevice& state) const +{ + auto execute = this->make_executor( + params, state, GaussianRoughnessExecutorBuilder{data_.device_ref()}); + + static ActionLauncher const launch_kernel( + *this); + launch_kernel(state, execute); +} + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh b/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh index 658de0f83f..639098deaf 100644 --- a/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh +++ b/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh @@ -6,33 +6,33 @@ //---------------------------------------------------------------------------// #pragma once -#include "corecel/data/CollectionBuilder.hh" #include "corecel/data/CollectionMirror.hh" -#include "celeritas/inp/SurfacePhysics.hh" #include "GaussianRoughnessData.hh" -#include "GaussianRoughnessExecutor.hh" +#include "RoughnessModel.hh" namespace celeritas { +namespace inp +{ +struct GaussianRoughness; +} namespace optical { //---------------------------------------------------------------------------// /*! */ -class GaussianRoughnessModelController +class GaussianRoughnessModel : public RoughnessModel { public: - constexpr static std::string_view label = "gaussian"; + using InputT = inp::GaussianRoughness; - GaussianRoughnessModelController( - std::vector const& input); + GaussianRoughnessModel(SurfaceModelId model, + std::vector surfaces, + std::vector const& inputs); - template - GaussianRoughnessExecutorBuilder make_builder() const - { - return GaussianRoughnessExecutorBuilder{data_.ref()}; - } + void step(CoreParams const& params, CoreStateHost& state) const final; + void step(CoreParams const&, CoreStateDevice&) const final; private: CollectionMirror data_; diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc new file mode 100644 index 0000000000..bee3812f75 --- /dev/null +++ b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc @@ -0,0 +1,48 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/PolishedRoughnessModel.cc +//---------------------------------------------------------------------------// +#include "PolishedRoughnessModel.hh" + +#include "celeritas/inp/SurfacePhysics.hh" +#include "celeritas/optical/CoreParams.hh" +#include "celeritas/optical/CoreState.hh" +#include "celeritas/optical/action/ActionLauncher.hh" +#include "celeritas/optical/surface/TrackSlotExecutor.hh" + +#include "PolishedRoughnessExecutor.hh" + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// + +PolishedRoughnessModel::PolishedRoughnessModel( + SurfaceModelId model, + std::vector surfaces, + std::vector const&) + : RoughnessModel(model, "polished", std::move(surfaces)) +{ +} + +void PolishedRoughnessModel::step(CoreParams const& params, + CoreStateHost& state) const +{ + launch_action(state, + this->make_executor( + params, state, PolishedRoughnessExecutorBuilder{})); +} + +#if !CELER_USE_DEVICE +void PolishedRoughnessModel::step(CoreParams const&, CoreStateDevice&) const +{ + CELER_NOT_IMPLEMENTED("CUDA OR HIP"); +} +#endif + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cu b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cu new file mode 100644 index 0000000000..000cf8b441 --- /dev/null +++ b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cu @@ -0,0 +1,34 @@ +//------------------------------ -*- cuda -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/PolishedRoughnessModel.cu +//---------------------------------------------------------------------------// +#include "PolishedRoughnessModel.hh" + +#include "celeritas/optical/CoreParams.hh" +#include "celeritas/optical/CoreState.hh" +#include "celeritas/optical/action/ActionLauncher.device.hh" +#include "celeritas/optical/surface/TrackSlotExecutor.hh" + +#include "PolishedRoughnessExecutor.hh" + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// +void PolishedRoughnessModel::step(CoreParams const& params, + CoreStateDevice& state) const +{ + auto execute = this->make_executor( + params, state, PolishedRoughnessExecutorBuilder{}); + + static ActionLauncher const launch_kernel( + *this); + launch_kernel(state, execute); +} + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh b/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh index fc059a6cac..4dd5092811 100644 --- a/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh +++ b/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh @@ -6,10 +6,7 @@ //---------------------------------------------------------------------------// #pragma once -#include -#include - -#include "PolishedRoughnessExecutor.hh" +#include "RoughnessModel.hh" namespace celeritas { @@ -21,25 +18,18 @@ namespace optical { //---------------------------------------------------------------------------// /*! - * Brief class description. - * - * Optional detailed class description, and possibly example usage: - * \code - PolishedRoughnessModel ...; - \endcode */ -class PolishedRoughnessModelController +class PolishedRoughnessModel : public RoughnessModel { public: - constexpr static std::string_view label = "polished"; + using InputT = inp::NoRoughness; - PolishedRoughnessModelController(std::vector const&) {} + PolishedRoughnessModel(SurfaceModelId model, + std::vector surfaces, + std::vector const&); - template - PolishedRoughnessExecutorBuilder make_builder() const - { - return PolishedRoughnessExecutorBuilder{}; - } + void step(CoreParams const& params, CoreStateHost& state) const final; + void step(CoreParams const&, CoreStateDevice&) const final; }; //---------------------------------------------------------------------------// diff --git a/src/celeritas/optical/surface/model/RoughnessModel.cc b/src/celeritas/optical/surface/model/RoughnessModel.cc deleted file mode 100644 index 17f0c354f8..0000000000 --- a/src/celeritas/optical/surface/model/RoughnessModel.cc +++ /dev/null @@ -1,49 +0,0 @@ -//------------------------------- -*- C++ -*- -------------------------------// -// Copyright Celeritas contributors: see top-level COPYRIGHT file for details -// SPDX-License-Identifier: (Apache-2.0 OR MIT) -//---------------------------------------------------------------------------// -//! \file celeritas/optical/surface/model/RoughnessModel.cc -//---------------------------------------------------------------------------// -#include "RoughnessModel.hh" - -#include "celeritas/optical/CoreParams.hh" -#include "celeritas/optical/CoreState.hh" -#include "celeritas/optical/action/ActionLauncher.hh" -#include "celeritas/optical/surface/TrackSlotExecutor.hh" - -#include "FakeExecutor.hh" - -namespace celeritas -{ -namespace optical -{ -//---------------------------------------------------------------------------// -template -void RoughnessModel::step(CoreParams const& params, - CoreStateHost& state) const -{ - launch_action(state, - make_surface_physics_executor(params.ptr(), - state.ptr(), - SurfacePhysicsOrder::roughness, - this->surface_model_id(), - FakeExecutor{})); - // RoughnessApplier{ - // controller_.template make_builder()})); -} - -#if !CELER_USE_DEVICE -template -void RoughnessModel::step(CoreParams const&, CoreStateDevice&) const -{ - CELER_NOT_IMPLEMENTED("CUDA OR HIP"); -} -#endif - -template class RoughnessModel; -template class RoughnessModel; -template class RoughnessModel; - -//---------------------------------------------------------------------------// -} // namespace optical -} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/RoughnessModel.hh b/src/celeritas/optical/surface/model/RoughnessModel.hh index 7769b917ef..da1ed41a9e 100644 --- a/src/celeritas/optical/surface/model/RoughnessModel.hh +++ b/src/celeritas/optical/surface/model/RoughnessModel.hh @@ -6,37 +6,28 @@ //---------------------------------------------------------------------------// #pragma once +#include "celeritas/optical/CoreParams.hh" +#include "celeritas/optical/CoreState.hh" #include "celeritas/optical/surface/SurfaceModel.hh" +#include "celeritas/optical/surface/TrackSlotExecutor.hh" -#include "GaussianRoughnessModel.hh" -#include "PolishedRoughnessModel.hh" #include "RoughnessApplier.hh" -#include "SmearRoughnessModel.hh" namespace celeritas { namespace optical { //---------------------------------------------------------------------------// -/*! - * Brief class description. - * - * Optional detailed class description, and possibly example usage: - * \code - RoughnessModel ...; - \endcode - */ -template class RoughnessModel : public SurfaceModel { public: template - static std::shared_ptr> - build_model(SurfaceModelId model_id, - std::map const& layer_map) + static std::shared_ptr + from_input(SurfaceModelId model_id, + std::map const& layer_map) { std::vector surfaces; - std::vector inputs; + std::vector inputs; for (auto const& [surface, input] : layer_map) { @@ -48,41 +39,34 @@ class RoughnessModel : public SurfaceModel CELER_ENSURE(surfaces.size() == layer_map.size()); CELER_ENSURE(inputs.size() == layer_map.size()); - return std::make_shared(model_id, - Controller::label, - std::move(surfaces), - Controller{inputs}); + return std::make_shared(model_id, std::move(surfaces), inputs); } std::vector get_surfaces() const final { return surfaces_; } - void step(CoreParams const& params, CoreStateHost& state) const final; - - void step(CoreParams const&, CoreStateDevice&) const final; - + protected: RoughnessModel(SurfaceModelId model_id, std::string_view label, - std::vector surfaces, - Controller controller) - : SurfaceModel(model_id, label) - , controller_(std::move(controller)) - , surfaces_(std::move(surfaces)) + std::vector surfaces) + : SurfaceModel(model_id, label), surfaces_(std::move(surfaces)) { } - protected: - Controller controller_; + template + auto + make_executor(CoreParams const& params, CoreState& state, E&& exec) const + { + return make_surface_physics_executor( + params.ptr(), + state.ptr(), + SurfacePhysicsOrder::roughness, + this->surface_model_id(), + RoughnessApplier{std::forward(exec)}); + } + std::vector surfaces_; }; -extern template class RoughnessModel; -extern template class RoughnessModel; -extern template class RoughnessModel; - -using SmearRoughnessModel = RoughnessModel; -using PolishedRoughnessModel = RoughnessModel; -using GaussianRoughnessModel = RoughnessModel; - //---------------------------------------------------------------------------// } // namespace optical } // namespace celeritas diff --git a/src/celeritas/optical/surface/model/SmearRoughnessModel.cc b/src/celeritas/optical/surface/model/SmearRoughnessModel.cc new file mode 100644 index 0000000000..2ba0047258 --- /dev/null +++ b/src/celeritas/optical/surface/model/SmearRoughnessModel.cc @@ -0,0 +1,61 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/SmearRoughnessModel.cc +//---------------------------------------------------------------------------// +#include "SmearRoughnessModel.hh" + +#include "corecel/data/CollectionBuilder.hh" +#include "celeritas/inp/SurfacePhysics.hh" +#include "celeritas/optical/CoreParams.hh" +#include "celeritas/optical/CoreState.hh" +#include "celeritas/optical/action/ActionLauncher.hh" +#include "celeritas/optical/surface/TrackSlotExecutor.hh" + +#include "SmearRoughnessExecutor.hh" + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// +SmearRoughnessModel::SmearRoughnessModel(SurfaceModelId model, + std::vector surfaces, + std::vector const& inputs) + : RoughnessModel(model, "smear", std::move(surfaces)) +{ + HostVal data; + auto build_roughness = ::celeritas::make_builder(&data.roughness); + + for (auto const& smear : inputs) + { + CELER_ENSURE(smear); + build_roughness.push_back(smear.roughness); + } + + CELER_ENSURE(data); + CELER_ENSURE(data.roughness.size() == inputs.size()); + + data_ = CollectionMirror{std::move(data)}; +} + +void SmearRoughnessModel::step(CoreParams const& params, + CoreStateHost& state) const +{ + launch_action( + state, + this->make_executor( + params, state, SmearRoughnessExecutorBuilder{data_.host_ref()})); +} + +#if !CELER_USE_DEVICE +void SmearRoughnessModel::step(CoreParams const&, CoreStateDevice&) const +{ + CELER_NOT_IMPLEMENTED("CUDA OR HIP"); +} +#endif + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/RoughnessModel.cu b/src/celeritas/optical/surface/model/SmearRoughnessModel.cu similarity index 52% rename from src/celeritas/optical/surface/model/RoughnessModel.cu rename to src/celeritas/optical/surface/model/SmearRoughnessModel.cu index 5568eb0809..3a610723d9 100644 --- a/src/celeritas/optical/surface/model/RoughnessModel.cu +++ b/src/celeritas/optical/surface/model/SmearRoughnessModel.cu @@ -2,42 +2,33 @@ // Copyright Celeritas contributors: see top-level COPYRIGHT file for details // SPDX-License-Identifier: (Apache-2.0 OR MIT) //---------------------------------------------------------------------------// -//! \file celeritas/optical/surface/model/RoughnessModel.cu +//! \file celeritas/optical/surface/model/SmearRoughnessModel.cu //---------------------------------------------------------------------------// -#include "RoughnessModel.hh" +#include "SmearRoughnessModel.hh" #include "celeritas/optical/CoreParams.hh" #include "celeritas/optical/CoreState.hh" #include "celeritas/optical/action/ActionLauncher.device.hh" #include "celeritas/optical/surface/TrackSlotExecutor.hh" +#include "SmearRoughnessExecutor.hh" + namespace celeritas { namespace optical { //---------------------------------------------------------------------------// -template -void RoughnessModel::step(CoreParams const& /* params */, - CoreStateDevice& /* state */) const +void SmearRoughnessModel::step(CoreParams const& params, + CoreStateDevice& state) const { - /* - auto execute = make_surface_physics_executor( - params.ptr(), - state.ptr(), - SurfacePhysicsOrder::roughness, - this->surface_model_id(), - RoughnessApplier{ - controller_.template make_builder()}); + auto execute = this->make_executor( + params, state, SmearRoughnessExecutorBuilder{data_.device_ref()}); - static ActionLauncher const - launch_kernel(*this); launch_kernel(state, execute); - */ + static ActionLauncher const launch_kernel( + *this); + launch_kernel(state, execute); } -template class RoughnessModel; -template class RoughnessModel; -template class RoughnessModel; - //---------------------------------------------------------------------------// } // namespace optical } // namespace celeritas diff --git a/src/celeritas/optical/surface/model/SmearRoughnessModel.hh b/src/celeritas/optical/surface/model/SmearRoughnessModel.hh index 467cbfc7cc..b6b66928f4 100644 --- a/src/celeritas/optical/surface/model/SmearRoughnessModel.hh +++ b/src/celeritas/optical/surface/model/SmearRoughnessModel.hh @@ -6,38 +6,33 @@ //---------------------------------------------------------------------------// #pragma once -#include "corecel/data/CollectionBuilder.hh" #include "corecel/data/CollectionMirror.hh" -#include "celeritas/inp/SurfacePhysics.hh" +#include "RoughnessModel.hh" #include "SmearRoughnessData.hh" -#include "SmearRoughnessExecutor.hh" namespace celeritas { +namespace inp +{ +struct SmearRoughness; +} namespace optical { //---------------------------------------------------------------------------// /*! - * Brief class description. - * - * Optional detailed class description, and possibly example usage: - * \code - SmearRoughnessModel ...; - \endcode */ -class SmearRoughnessModelController +class SmearRoughnessModel : public RoughnessModel { public: - constexpr static std::string_view label = "smear"; + using InputT = inp::SmearRoughness; - SmearRoughnessModelController(std::vector const& input); + SmearRoughnessModel(SurfaceModelId model, + std::vector surfaces, + std::vector const& inputs); - template - SmearRoughnessExecutorBuilder make_builder() const - { - return SmearRoughnessExecutorBuilder{data_.ref()}; - } + void step(CoreParams const& params, CoreStateHost& state) const final; + void step(CoreParams const&, CoreStateDevice&) const final; private: CollectionMirror data_; From 03f801c738d7321cc150905982c6940e1bee8234 Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Fri, 29 Aug 2025 16:39:26 -0500 Subject: [PATCH 07/22] Switch roughness model to builtin surface model --- .../optical/surface/SurfacePhysicsParams.cc | 2 +- .../surface/model/BuiltinSurfaceModel.hh | 97 +++++++++++++++++++ .../surface/model/GaussianRoughnessModel.cc | 3 +- .../surface/model/GaussianRoughnessModel.hh | 5 +- .../surface/model/PolishedRoughnessModel.cc | 3 +- .../surface/model/PolishedRoughnessModel.hh | 5 +- .../optical/surface/model/RoughnessModel.hh | 72 -------------- .../surface/model/SmearRoughnessModel.cc | 3 +- .../surface/model/SmearRoughnessModel.hh | 5 +- 9 files changed, 113 insertions(+), 82 deletions(-) create mode 100644 src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh delete mode 100644 src/celeritas/optical/surface/model/RoughnessModel.hh diff --git a/src/celeritas/optical/surface/SurfacePhysicsParams.cc b/src/celeritas/optical/surface/SurfacePhysicsParams.cc index ecbd12b644..0c77c4d500 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsParams.cc +++ b/src/celeritas/optical/surface/SurfacePhysicsParams.cc @@ -86,7 +86,7 @@ class FakeModelBuilder { if (!layer_map.empty()) { - models_.push_back(RoughnessModel::from_input( + models_.push_back(builtin_model_from_input( SurfaceModelId(models_.size()), layer_map)); num_surf_ += layer_map.size(); } diff --git a/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh b/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh new file mode 100644 index 0000000000..e284fe4b91 --- /dev/null +++ b/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh @@ -0,0 +1,97 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/BuiltinSurfaceModel.hh +//---------------------------------------------------------------------------// +#pragma once + +#include "celeritas/optical/CoreParams.hh" +#include "celeritas/optical/CoreState.hh" +#include "celeritas/optical/surface/SurfaceModel.hh" +#include "celeritas/optical/surface/TrackSlotExecutor.hh" + +#include "RoughnessApplier.hh" + +namespace celeritas +{ +namespace optical +{ +namespace +{ +template +struct BuiltinApplier; + +template<> +struct BuiltinApplier +{ + template + using Applier = RoughnessApplier; +}; + +} // namespace +//---------------------------------------------------------------------------// +/*! + * Brief class description. + * + * Optional detailed class description, and possibly example usage: + * \code + BuiltinSurfaceModel ...; + \endcode + */ +template +class BuiltinSurfaceModel : public SurfaceModel +{ + public: + template + using Applier = typename BuiltinApplier::Applier; + + std::vector get_surfaces() const final { return surfaces_; } + + protected: + BuiltinSurfaceModel(SurfaceModelId model_id, + std::string_view label, + std::vector surfaces) + : SurfaceModel(model_id, label), surfaces_(std::move(surfaces)) + { + } + + template + auto + make_executor(CoreParams const& params, CoreState& state, E&& exec) const + { + return make_surface_physics_executor(params.ptr(), + state.ptr(), + S, + this->surface_model_id(), + Applier{std::forward(exec)}); + } + + private: + std::vector surfaces_; +}; + +template +std::shared_ptr builtin_model_from_input( + SurfaceModelId model_id, + std::map const& layer_map) +{ + std::vector surfaces; + std::vector inputs; + + for (auto const& [surface, input] : layer_map) + { + CELER_ENSURE(surface); + surfaces.push_back(surface); + inputs.push_back(input); + } + + CELER_ENSURE(surfaces.size() == layer_map.size()); + CELER_ENSURE(inputs.size() == layer_map.size()); + + return std::make_shared(model_id, std::move(surfaces), inputs); +} + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc b/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc index 2d0f843062..8ba772136b 100644 --- a/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc +++ b/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc @@ -24,7 +24,8 @@ GaussianRoughnessModel::GaussianRoughnessModel( SurfaceModelId model, std::vector surfaces, std::vector const& inputs) - : RoughnessModel(model, "gaussian", std::move(surfaces)) + : BuiltinSurfaceModel( + model, "gaussian", std::move(surfaces)) { HostVal data; auto build_sigma_alpha = ::celeritas::make_builder(&data.sigma_alpha); diff --git a/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh b/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh index 639098deaf..df6d41c4d1 100644 --- a/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh +++ b/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh @@ -8,8 +8,8 @@ #include "corecel/data/CollectionMirror.hh" +#include "BuiltinSurfaceModel.hh" #include "GaussianRoughnessData.hh" -#include "RoughnessModel.hh" namespace celeritas { @@ -22,7 +22,8 @@ namespace optical //---------------------------------------------------------------------------// /*! */ -class GaussianRoughnessModel : public RoughnessModel +class GaussianRoughnessModel + : public BuiltinSurfaceModel { public: using InputT = inp::GaussianRoughness; diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc index bee3812f75..8e119fbb5d 100644 --- a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc +++ b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc @@ -24,7 +24,8 @@ PolishedRoughnessModel::PolishedRoughnessModel( SurfaceModelId model, std::vector surfaces, std::vector const&) - : RoughnessModel(model, "polished", std::move(surfaces)) + : BuiltinSurfaceModel( + model, "polished", std::move(surfaces)) { } diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh b/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh index 4dd5092811..fe5d0a0e90 100644 --- a/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh +++ b/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh @@ -6,7 +6,7 @@ //---------------------------------------------------------------------------// #pragma once -#include "RoughnessModel.hh" +#include "BuiltinSurfaceModel.hh" namespace celeritas { @@ -19,7 +19,8 @@ namespace optical //---------------------------------------------------------------------------// /*! */ -class PolishedRoughnessModel : public RoughnessModel +class PolishedRoughnessModel + : public BuiltinSurfaceModel { public: using InputT = inp::NoRoughness; diff --git a/src/celeritas/optical/surface/model/RoughnessModel.hh b/src/celeritas/optical/surface/model/RoughnessModel.hh deleted file mode 100644 index da1ed41a9e..0000000000 --- a/src/celeritas/optical/surface/model/RoughnessModel.hh +++ /dev/null @@ -1,72 +0,0 @@ -//------------------------------- -*- C++ -*- -------------------------------// -// Copyright Celeritas contributors: see top-level COPYRIGHT file for details -// SPDX-License-Identifier: (Apache-2.0 OR MIT) -//---------------------------------------------------------------------------// -//! \file celeritas/optical/surface/model/RoughnessModel.hh -//---------------------------------------------------------------------------// -#pragma once - -#include "celeritas/optical/CoreParams.hh" -#include "celeritas/optical/CoreState.hh" -#include "celeritas/optical/surface/SurfaceModel.hh" -#include "celeritas/optical/surface/TrackSlotExecutor.hh" - -#include "RoughnessApplier.hh" - -namespace celeritas -{ -namespace optical -{ -//---------------------------------------------------------------------------// -class RoughnessModel : public SurfaceModel -{ - public: - template - static std::shared_ptr - from_input(SurfaceModelId model_id, - std::map const& layer_map) - { - std::vector surfaces; - std::vector inputs; - - for (auto const& [surface, input] : layer_map) - { - CELER_ENSURE(surface); - surfaces.push_back(surface); - inputs.push_back(input); - } - - CELER_ENSURE(surfaces.size() == layer_map.size()); - CELER_ENSURE(inputs.size() == layer_map.size()); - - return std::make_shared(model_id, std::move(surfaces), inputs); - } - - std::vector get_surfaces() const final { return surfaces_; } - - protected: - RoughnessModel(SurfaceModelId model_id, - std::string_view label, - std::vector surfaces) - : SurfaceModel(model_id, label), surfaces_(std::move(surfaces)) - { - } - - template - auto - make_executor(CoreParams const& params, CoreState& state, E&& exec) const - { - return make_surface_physics_executor( - params.ptr(), - state.ptr(), - SurfacePhysicsOrder::roughness, - this->surface_model_id(), - RoughnessApplier{std::forward(exec)}); - } - - std::vector surfaces_; -}; - -//---------------------------------------------------------------------------// -} // namespace optical -} // namespace celeritas diff --git a/src/celeritas/optical/surface/model/SmearRoughnessModel.cc b/src/celeritas/optical/surface/model/SmearRoughnessModel.cc index 2ba0047258..fa94ab1a7f 100644 --- a/src/celeritas/optical/surface/model/SmearRoughnessModel.cc +++ b/src/celeritas/optical/surface/model/SmearRoughnessModel.cc @@ -23,7 +23,8 @@ namespace optical SmearRoughnessModel::SmearRoughnessModel(SurfaceModelId model, std::vector surfaces, std::vector const& inputs) - : RoughnessModel(model, "smear", std::move(surfaces)) + : BuiltinSurfaceModel( + model, "smear", std::move(surfaces)) { HostVal data; auto build_roughness = ::celeritas::make_builder(&data.roughness); diff --git a/src/celeritas/optical/surface/model/SmearRoughnessModel.hh b/src/celeritas/optical/surface/model/SmearRoughnessModel.hh index b6b66928f4..3aa6cc79b6 100644 --- a/src/celeritas/optical/surface/model/SmearRoughnessModel.hh +++ b/src/celeritas/optical/surface/model/SmearRoughnessModel.hh @@ -8,7 +8,7 @@ #include "corecel/data/CollectionMirror.hh" -#include "RoughnessModel.hh" +#include "BuiltinSurfaceModel.hh" #include "SmearRoughnessData.hh" namespace celeritas @@ -22,7 +22,8 @@ namespace optical //---------------------------------------------------------------------------// /*! */ -class SmearRoughnessModel : public RoughnessModel +class SmearRoughnessModel + : public BuiltinSurfaceModel { public: using InputT = inp::SmearRoughness; From fa0ac7ba250ac20d3cd1edf02ee4db9aec7c4a74 Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Fri, 29 Aug 2025 20:57:57 -0500 Subject: [PATCH 08/22] Refined some of builtin roughness models --- .../surface/model/BuiltinSurfaceModel.hh | 25 ++++++++++++++++++- .../surface/model/GaussianRoughnessModel.cc | 3 +-- .../surface/model/GaussianRoughnessModel.hh | 3 +-- .../surface/model/PolishedRoughnessModel.cc | 3 +-- .../surface/model/PolishedRoughnessModel.hh | 3 +-- .../optical/surface/model/RoughnessApplier.hh | 16 +++--------- .../surface/model/SmearRoughnessModel.cc | 3 +-- .../surface/model/SmearRoughnessModel.hh | 3 +-- 8 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh b/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh index e284fe4b91..161f25d4c8 100644 --- a/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh +++ b/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh @@ -19,8 +19,24 @@ namespace optical { namespace { + +template +struct TrivialApplier +{ + T const& executor; + + inline CELER_FUNCTION void operator()(CoreTrackView& track) const + { + executor(track); + } +}; + template -struct BuiltinApplier; +struct BuiltinApplier +{ + template + using Applier = TrivialApplier; +}; template<> struct BuiltinApplier @@ -92,6 +108,13 @@ std::shared_ptr builtin_model_from_input( return std::make_shared(model_id, std::move(surfaces), inputs); } +using BuiltinRoughnessModel + = BuiltinSurfaceModel; +using BuiltinReflectivityModel + = BuiltinSurfaceModel; +using BuiltinInteractionModel + = BuiltinSurfaceModel; + //---------------------------------------------------------------------------// } // namespace optical } // namespace celeritas diff --git a/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc b/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc index 8ba772136b..6da36781a4 100644 --- a/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc +++ b/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc @@ -24,8 +24,7 @@ GaussianRoughnessModel::GaussianRoughnessModel( SurfaceModelId model, std::vector surfaces, std::vector const& inputs) - : BuiltinSurfaceModel( - model, "gaussian", std::move(surfaces)) + : BuiltinRoughnessModel(model, "gaussian", std::move(surfaces)) { HostVal data; auto build_sigma_alpha = ::celeritas::make_builder(&data.sigma_alpha); diff --git a/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh b/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh index df6d41c4d1..c2c803eb68 100644 --- a/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh +++ b/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh @@ -22,8 +22,7 @@ namespace optical //---------------------------------------------------------------------------// /*! */ -class GaussianRoughnessModel - : public BuiltinSurfaceModel +class GaussianRoughnessModel : public BuiltinRoughnessModel { public: using InputT = inp::GaussianRoughness; diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc index 8e119fbb5d..8612b655c2 100644 --- a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc +++ b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc @@ -24,8 +24,7 @@ PolishedRoughnessModel::PolishedRoughnessModel( SurfaceModelId model, std::vector surfaces, std::vector const&) - : BuiltinSurfaceModel( - model, "polished", std::move(surfaces)) + : BuiltinRoughnessModel(model, "polished", std::move(surfaces)) { } diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh b/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh index fe5d0a0e90..90b0a6aa2f 100644 --- a/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh +++ b/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh @@ -19,8 +19,7 @@ namespace optical //---------------------------------------------------------------------------// /*! */ -class PolishedRoughnessModel - : public BuiltinSurfaceModel +class PolishedRoughnessModel : public BuiltinRoughnessModel { public: using InputT = inp::NoRoughness; diff --git a/src/celeritas/optical/surface/model/RoughnessApplier.hh b/src/celeritas/optical/surface/model/RoughnessApplier.hh index 6583d62b3f..6bbc4c6f41 100644 --- a/src/celeritas/optical/surface/model/RoughnessApplier.hh +++ b/src/celeritas/optical/surface/model/RoughnessApplier.hh @@ -17,22 +17,12 @@ namespace optical /*! */ template -class RoughnessApplier +struct RoughnessApplier { - public: - CELER_FUNCTION RoughnessApplier(T&& executor_builder) - : executor_builder_{celeritas::forward(executor_builder)} - { - } - + T const& executor_builder; inline CELER_FUNCTION void operator()(CoreTrackView& track) const; - - private: - T executor_builder_; }; -// template CELER_FUNCTION RoughnessApplier( - //---------------------------------------------------------------------------// // INLINE DEFINITIONS //---------------------------------------------------------------------------// @@ -51,7 +41,7 @@ CELER_FUNCTION void RoughnessApplier::operator()(CoreTrackView& track) const normal = -normal; } - auto sample = executor_builder_(model_view, track.geometry().dir(), normal); + auto sample = executor_builder(model_view, track.geometry().dir(), normal); s_physics.facet_normal(sample(rng)); } diff --git a/src/celeritas/optical/surface/model/SmearRoughnessModel.cc b/src/celeritas/optical/surface/model/SmearRoughnessModel.cc index fa94ab1a7f..9ed6baf12c 100644 --- a/src/celeritas/optical/surface/model/SmearRoughnessModel.cc +++ b/src/celeritas/optical/surface/model/SmearRoughnessModel.cc @@ -23,8 +23,7 @@ namespace optical SmearRoughnessModel::SmearRoughnessModel(SurfaceModelId model, std::vector surfaces, std::vector const& inputs) - : BuiltinSurfaceModel( - model, "smear", std::move(surfaces)) + : BuiltinRoughnessModel(model, "smear", std::move(surfaces)) { HostVal data; auto build_roughness = ::celeritas::make_builder(&data.roughness); diff --git a/src/celeritas/optical/surface/model/SmearRoughnessModel.hh b/src/celeritas/optical/surface/model/SmearRoughnessModel.hh index 3aa6cc79b6..d0ca8d63bc 100644 --- a/src/celeritas/optical/surface/model/SmearRoughnessModel.hh +++ b/src/celeritas/optical/surface/model/SmearRoughnessModel.hh @@ -22,8 +22,7 @@ namespace optical //---------------------------------------------------------------------------// /*! */ -class SmearRoughnessModel - : public BuiltinSurfaceModel +class SmearRoughnessModel : public BuiltinRoughnessModel { public: using InputT = inp::SmearRoughness; From e9ab07c4a2da3c280d3153ebc0dc7bfba1588627 Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Fri, 29 Aug 2025 22:03:52 -0500 Subject: [PATCH 09/22] Add missing data file from cherry-pick --- .../surface/model/GaussianRoughnessData.hh | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/celeritas/optical/surface/model/GaussianRoughnessData.hh diff --git a/src/celeritas/optical/surface/model/GaussianRoughnessData.hh b/src/celeritas/optical/surface/model/GaussianRoughnessData.hh new file mode 100644 index 0000000000..05e11204ac --- /dev/null +++ b/src/celeritas/optical/surface/model/GaussianRoughnessData.hh @@ -0,0 +1,63 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/model/GaussianRoughnessData.hh +//---------------------------------------------------------------------------// +#pragma once + +#include "corecel/Macros.hh" +#include "corecel/data/Collection.hh" +#include "celeritas/Types.hh" +#include "celeritas/optical/surface/SurfaceModel.hh" + +namespace celeritas +{ +namespace optical +{ +//---------------------------------------------------------------------------// +/*! + * Brief class description. + * + * Optional detailed class description, and possibly example usage: + * \code + GaussianRoughnessData ...; + \endcode + */ +template +struct GaussianRoughnessData +{ + //!@{ + //! \name Type aliases + template + using SurfaceItems = Collection; + //!@} + + //// DATA ///// + + SurfaceItems sigma_alpha; + + //// METHODS //// + + //! True if assigned + explicit CELER_FUNCTION operator bool() const + { + return !sigma_alpha.empty(); + } + + //! Assign from another set of data + template + GaussianRoughnessData& + operator=(GaussianRoughnessData const& other) + { + CELER_EXPECT(other); + + sigma_alpha = other.sigma_alpha; + + return *this; + } +}; + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas From 0c591a84cad3fbfada8d9d7f5f44a17b2df7ba66 Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Fri, 29 Aug 2025 23:09:45 -0500 Subject: [PATCH 10/22] Add documentation --- .../optical/surface/SurfaceModelView.hh | 44 ++++++- .../optical/surface/SurfacePhysicsParams.cc | 2 +- .../optical/surface/TrackSlotExecutor.hh | 17 ++- .../surface/model/BuiltinSurfaceModel.hh | 117 +++++++++++++----- .../surface/model/GaussianRoughnessData.hh | 7 +- .../model/GaussianRoughnessExecutor.hh | 29 +++-- .../surface/model/GaussianRoughnessModel.cc | 13 +- .../surface/model/GaussianRoughnessModel.cu | 5 +- .../surface/model/GaussianRoughnessModel.hh | 13 ++ .../model/PolishedRoughnessExecutor.hh | 40 ++++-- .../surface/model/PolishedRoughnessModel.cc | 17 ++- .../surface/model/PolishedRoughnessModel.cu | 7 +- .../surface/model/PolishedRoughnessModel.hh | 13 ++ .../optical/surface/model/RoughnessApplier.hh | 22 +++- .../surface/model/SmearRoughnessData.hh | 7 +- .../surface/model/SmearRoughnessExecutor.hh | 28 +++-- .../surface/model/SmearRoughnessModel.cc | 18 ++- .../surface/model/SmearRoughnessModel.cu | 5 +- .../surface/model/SmearRoughnessModel.hh | 13 ++ src/celeritas/phys/SurfaceModel.hh | 2 +- test/celeritas/phys/SurfacePhysicsMap.test.cc | 2 +- 21 files changed, 331 insertions(+), 90 deletions(-) diff --git a/src/celeritas/optical/surface/SurfaceModelView.hh b/src/celeritas/optical/surface/SurfaceModelView.hh index 65c1f378c7..6ee23d13fa 100644 --- a/src/celeritas/optical/surface/SurfaceModelView.hh +++ b/src/celeritas/optical/surface/SurfaceModelView.hh @@ -15,12 +15,10 @@ namespace optical { //---------------------------------------------------------------------------// /*! - * Brief class description. + * Optical surface data for a model. * - * Optional detailed class description, and possibly example usage: - * \code - SurfaceModelView ...; - \endcode + * Wraps common behavior for querying the surface model data for a given + * physics surface interface. */ class SurfaceModelView { @@ -31,14 +29,23 @@ class SurfaceModelView //!@} public: + // Construct from a direction and map view inline CELER_FUNCTION SurfaceModelView(SubsurfaceDirection, SurfacePhysicsMapView const&); + // Get subsurface track direction inline CELER_FUNCTION SubsurfaceDirection direction() const; - // inline CELER_FUNCTION PhysSurfaceId phys_surface_id() const; + + // Get surface model ID inline CELER_FUNCTION SurfaceModelId surface_model() const; + + // Get internal surface ID for the model inline CELER_FUNCTION InternalSurfaceId internal_surface_id() const; + + // Get pre-volume optical material inline CELER_FUNCTION OptMatId pre_material() const; + + // Get post-volume optical material inline CELER_FUNCTION OptMatId post_material() const; private: @@ -52,6 +59,7 @@ class SurfaceModelView // INLINE DEFINITIONS //---------------------------------------------------------------------------// /*! + * Construct from track direction and physics map view. */ CELER_FUNCTION SurfaceModelView::SurfaceModelView(SubsurfaceDirection dir, @@ -60,23 +68,47 @@ SurfaceModelView::SurfaceModelView(SubsurfaceDirection dir, { } +//---------------------------------------------------------------------------// +/*! + * Get the subsurface track direction pointing to this surface. + */ CELER_FUNCTION SubsurfaceDirection SurfaceModelView::direction() const { return SubsurfaceDirection::forward; } + +//---------------------------------------------------------------------------// +/*! + * Get the surface model for this physics surface. + */ CELER_FUNCTION SurfaceModelId SurfaceModelView::surface_model() const { return {}; } + +//---------------------------------------------------------------------------// +/*! + * Get the internal surface ID for the physics surface in this model. + */ CELER_FUNCTION auto SurfaceModelView::internal_surface_id() const -> InternalSurfaceId { return {}; } + +//---------------------------------------------------------------------------// +/*! + * Get the optical material before the interface. + */ CELER_FUNCTION OptMatId SurfaceModelView::pre_material() const { return {}; } + +//---------------------------------------------------------------------------// +/*! + * Get the optical material after the interface. + */ CELER_FUNCTION OptMatId SurfaceModelView::post_material() const { return {}; diff --git a/src/celeritas/optical/surface/SurfacePhysicsParams.cc b/src/celeritas/optical/surface/SurfacePhysicsParams.cc index 0c77c4d500..5702734bb0 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsParams.cc +++ b/src/celeritas/optical/surface/SurfacePhysicsParams.cc @@ -45,7 +45,7 @@ class FakeModel : public SurfaceModel CELER_ENSURE(layer_map.size() == surfaces_.size()); } - VecSurfaceLayer get_surfaces() const final { return surfaces_; } + VecSurfaceLayer const& get_surfaces() const final { return surfaces_; } void step(CoreParams const&, CoreStateHost&) const final {} void step(CoreParams const&, CoreStateDevice&) const final {} diff --git a/src/celeritas/optical/surface/TrackSlotExecutor.hh b/src/celeritas/optical/surface/TrackSlotExecutor.hh index 7c369827e9..7a3513080e 100644 --- a/src/celeritas/optical/surface/TrackSlotExecutor.hh +++ b/src/celeritas/optical/surface/TrackSlotExecutor.hh @@ -14,19 +14,32 @@ namespace celeritas namespace optical { //---------------------------------------------------------------------------// - +/*! + * Whether the track is undergoing a surface crossing and it matches the given + * step and model. + */ struct IsSurfaceModelEqual { SurfacePhysicsOrder step; SurfaceModelId model; - inline CELER_FUNCTION bool operator()(CoreTrackView const& track) const + //! Whether the surface model should be executed for the track + CELER_FUNCTION bool operator()(CoreTrackView const& track) const { return track.surface_physics().is_crossing_boundary() && track.surface_model(step).surface_model() == model; } }; +//---------------------------------------------------------------------------// +// FREE FUNCTIONS +//---------------------------------------------------------------------------// +/*! + * Construct a track slot executor that for a given surface step and model. + * + * The executor will launch kernels only on tracks which are undergoing a + * boundary crossing. + */ template inline CELER_FUNCTION decltype(auto) make_surface_physics_executor(CoreParamsPtr params, diff --git a/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh b/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh index 161f25d4c8..5d0498b013 100644 --- a/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh +++ b/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh @@ -19,7 +19,10 @@ namespace optical { namespace { - +//---------------------------------------------------------------------------// +/*! + * Trivial applier which just forwards the track to the executor. + */ template struct TrivialApplier { @@ -31,69 +34,123 @@ struct TrivialApplier } }; +//---------------------------------------------------------------------------// +/*! + * Template trait used to select applier wrapper for built-in executors. + */ template -struct BuiltinApplier +struct BuiltinApplier; + +template<> +struct BuiltinApplier +{ + template + using Applier = RoughnessApplier; +}; + +template<> +struct BuiltinApplier { template using Applier = TrivialApplier; }; template<> -struct BuiltinApplier +struct BuiltinApplier { template - using Applier = RoughnessApplier; + using Applier = TrivialApplier; }; } // namespace + //---------------------------------------------------------------------------// /*! - * Brief class description. + * Templated base class for built-in optical surface physics models. * - * Optional detailed class description, and possibly example usage: - * \code - BuiltinSurfaceModel ...; - \endcode + * Built-in surface physics models share a common format for their input data + * as well as the parameters to pass to their kernel launchers. The \c + * BuiltinApplier wrappers executor calls to factor out common behavior between + * surface physics steps. */ template class BuiltinSurfaceModel : public SurfaceModel { public: + //!@{ + //! \name Type aliases template using Applier = typename BuiltinApplier::Applier; + //!@} - std::vector get_surfaces() const final { return surfaces_; } + public: + //! Get surfaces handled by this model. + std::vector const& get_surfaces() const final + { + return surfaces_; + } protected: + // Construct from ID, label, and surfaces BuiltinSurfaceModel(SurfaceModelId model_id, std::string_view label, - std::vector surfaces) - : SurfaceModel(model_id, label), surfaces_(std::move(surfaces)) - { - } + std::vector surfaces); + // Construct executor with applier wrapper template - auto - make_executor(CoreParams const& params, CoreState& state, E&& exec) const - { - return make_surface_physics_executor(params.ptr(), - state.ptr(), - S, - this->surface_model_id(), - Applier{std::forward(exec)}); - } + auto make_executor(CoreParams const&, CoreState&, E&&) const; private: std::vector surfaces_; }; +//---------------------------------------------------------------------------// +// INLINE DEFINITIONS +//---------------------------------------------------------------------------// +/*! + * Construct from ID, label, and surfaces. + */ +template +BuiltinSurfaceModel::BuiltinSurfaceModel(SurfaceModelId model_id, + std::string_view label, + std::vector surfaces) + : SurfaceModel(model_id, label), surfaces_(std::move(surfaces)) +{ +} -template -std::shared_ptr builtin_model_from_input( +//---------------------------------------------------------------------------// +/*! + * Construct a surface physics executor with built-in applier wrapper. + */ +template +template +auto BuiltinSurfaceModel::make_executor(CoreParams const& params, + CoreState& state, + E&& exec) const +{ + return make_surface_physics_executor(params.ptr(), + state.ptr(), + S, + this->surface_model_id(), + Applier{std::forward(exec)}); +} + +//---------------------------------------------------------------------------// +// FREE FUNCTIONS +//---------------------------------------------------------------------------// +/*! + * Construct built-in model of type \c M from \c inp::SurfacePhysics surface + * layer map. + * + * The model \c M should have a type alias \c M::InputT which corresponds to + * the input type associated with each surface. + */ +template +std::shared_ptr builtin_model_from_input( SurfaceModelId model_id, - std::map const& layer_map) + std::map const& layer_map) { std::vector surfaces; - std::vector inputs; + std::vector inputs; for (auto const& [surface, input] : layer_map) { @@ -105,9 +162,13 @@ std::shared_ptr builtin_model_from_input( CELER_ENSURE(surfaces.size() == layer_map.size()); CELER_ENSURE(inputs.size() == layer_map.size()); - return std::make_shared(model_id, std::move(surfaces), inputs); + return std::make_shared(model_id, std::move(surfaces), inputs); } +//---------------------------------------------------------------------------// +// TEMPLATE ALIASES +//---------------------------------------------------------------------------// + using BuiltinRoughnessModel = BuiltinSurfaceModel; using BuiltinReflectivityModel diff --git a/src/celeritas/optical/surface/model/GaussianRoughnessData.hh b/src/celeritas/optical/surface/model/GaussianRoughnessData.hh index 05e11204ac..883dad6ee3 100644 --- a/src/celeritas/optical/surface/model/GaussianRoughnessData.hh +++ b/src/celeritas/optical/surface/model/GaussianRoughnessData.hh @@ -17,12 +17,7 @@ namespace optical { //---------------------------------------------------------------------------// /*! - * Brief class description. - * - * Optional detailed class description, and possibly example usage: - * \code - GaussianRoughnessData ...; - \endcode + * Storage for Gaussian roughness model data. */ template struct GaussianRoughnessData diff --git a/src/celeritas/optical/surface/model/GaussianRoughnessExecutor.hh b/src/celeritas/optical/surface/model/GaussianRoughnessExecutor.hh index 2d0177f672..731c7a98c2 100644 --- a/src/celeritas/optical/surface/model/GaussianRoughnessExecutor.hh +++ b/src/celeritas/optical/surface/model/GaussianRoughnessExecutor.hh @@ -17,7 +17,10 @@ namespace celeritas namespace optical { //---------------------------------------------------------------------------// -struct GaussianRoughnessExecutorBuilder +/*! + * Construct a sampling executor for a Gaussian roughness model. + */ +struct GaussianRoughnessExecutor { //!@{ //! \name Type aliases @@ -26,15 +29,25 @@ struct GaussianRoughnessExecutorBuilder NativeCRef data; - CELER_FUNCTION Sampler operator()(SurfaceModelView const& model, - Real3 const& dir, - Real3 const& normal) const - { - return Sampler( - dir, normal, data.sigma_alpha[model.internal_surface_id()]); - } + inline CELER_FUNCTION Sampler operator()(SurfaceModelView const& model, + Real3 const& dir, + Real3 const& normal) const; }; +//---------------------------------------------------------------------------// +// INLINE DEFINITIONS +//---------------------------------------------------------------------------// +/*! + * Construct sampler for the given model. + */ +CELER_FUNCTION auto +GaussianRoughnessExecutor::operator()(SurfaceModelView const& model, + Real3 const& dir, + Real3 const& normal) const -> Sampler +{ + return Sampler(dir, normal, data.sigma_alpha[model.internal_surface_id()]); +} + //---------------------------------------------------------------------------// } // namespace optical } // namespace celeritas diff --git a/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc b/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc index 6da36781a4..29c2363d61 100644 --- a/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc +++ b/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc @@ -20,6 +20,9 @@ namespace celeritas namespace optical { //---------------------------------------------------------------------------// +/*! + * Construct model from surfaces and inputs. + */ GaussianRoughnessModel::GaussianRoughnessModel( SurfaceModelId model, std::vector surfaces, @@ -41,15 +44,23 @@ GaussianRoughnessModel::GaussianRoughnessModel( data_ = CollectionMirror{std::move(data)}; } +//---------------------------------------------------------------------------// +/*! + * Launch kernel on host. + */ void GaussianRoughnessModel::step(CoreParams const& params, CoreStateHost& state) const { launch_action( state, this->make_executor( - params, state, GaussianRoughnessExecutorBuilder{data_.host_ref()})); + params, state, GaussianRoughnessExecutor{data_.host_ref()})); } +//---------------------------------------------------------------------------// +/*! + * Launch kernel on device. + */ #if !CELER_USE_DEVICE void GaussianRoughnessModel::step(CoreParams const&, CoreStateDevice&) const { diff --git a/src/celeritas/optical/surface/model/GaussianRoughnessModel.cu b/src/celeritas/optical/surface/model/GaussianRoughnessModel.cu index eb560afef9..107c0bab6c 100644 --- a/src/celeritas/optical/surface/model/GaussianRoughnessModel.cu +++ b/src/celeritas/optical/surface/model/GaussianRoughnessModel.cu @@ -18,11 +18,14 @@ namespace celeritas namespace optical { //---------------------------------------------------------------------------// +/*! + * Launch kernel on device. + */ void GaussianRoughnessModel::step(CoreParams const& params, CoreStateDevice& state) const { auto execute = this->make_executor( - params, state, GaussianRoughnessExecutorBuilder{data_.device_ref()}); + params, state, GaussianRoughnessExecutor{data_.device_ref()}); static ActionLauncher const launch_kernel( *this); diff --git a/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh b/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh index c2c803eb68..a28d7cd439 100644 --- a/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh +++ b/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh @@ -17,21 +17,34 @@ namespace inp { struct GaussianRoughness; } + namespace optical { //---------------------------------------------------------------------------// /*! + * Gaussian roughness surface model. + * + * Approximates the surface roughness of an optical surface with the UNIFIED + * Gaussian roughness model. */ class GaussianRoughnessModel : public BuiltinRoughnessModel { public: + //!@{ + //! \name Type aliases using InputT = inp::GaussianRoughness; + //!@} + public: + // Construct model from surfaces and inputs GaussianRoughnessModel(SurfaceModelId model, std::vector surfaces, std::vector const& inputs); + // Launch kernel on host void step(CoreParams const& params, CoreStateHost& state) const final; + + // Launch kernel on device void step(CoreParams const&, CoreStateDevice&) const final; private: diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessExecutor.hh b/src/celeritas/optical/surface/model/PolishedRoughnessExecutor.hh index ca761b825b..257f49019d 100644 --- a/src/celeritas/optical/surface/model/PolishedRoughnessExecutor.hh +++ b/src/celeritas/optical/surface/model/PolishedRoughnessExecutor.hh @@ -12,10 +12,15 @@ namespace celeritas { namespace optical { +class SurfaceModelView; //---------------------------------------------------------------------------// /*! + * Trivially sample a perfectly polished surface. + * + * A perfectly polished surface has the same local facet normal as the global + * normal. */ -struct PolishedRoughnessExecutor +struct PolishedRoughnessSampler { Real3 const& normal; @@ -26,15 +31,36 @@ struct PolishedRoughnessExecutor } }; -struct PolishedRoughnessExecutorBuilder +//---------------------------------------------------------------------------// +/*! + * Construct a sampling executor for a polished roughness model. + */ +struct PolishedRoughnessExecutor { - CELER_FUNCTION PolishedRoughnessExecutor operator()( - SurfaceModelView const&, Real3 const&, Real3 const& normal) const - { - return PolishedRoughnessExecutor{normal}; - } + //!@{ + //! name Type aliases + using Sampler = PolishedRoughnessSampler; + //!@} + + inline CELER_FUNCTION Sampler operator()(SurfaceModelView const&, + Real3 const&, + Real3 const& normal) const; }; +//---------------------------------------------------------------------------// +// INLINE DEFINITIONS +//---------------------------------------------------------------------------// +/*! + * Construct polished roughness sampler. + */ +CELER_FUNCTION auto +PolishedRoughnessExecutor::operator()(SurfaceModelView const&, + Real3 const&, + Real3 const& normal) const -> Sampler +{ + return Sampler{normal}; +} + //---------------------------------------------------------------------------// } // namespace optical } // namespace celeritas diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc index 8612b655c2..7e04ec7bba 100644 --- a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc +++ b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc @@ -19,7 +19,9 @@ namespace celeritas namespace optical { //---------------------------------------------------------------------------// - +/*! + * Construct model from surfaces and inputs. + */ PolishedRoughnessModel::PolishedRoughnessModel( SurfaceModelId model, std::vector surfaces, @@ -28,14 +30,21 @@ PolishedRoughnessModel::PolishedRoughnessModel( { } +//---------------------------------------------------------------------------// +/*! + * Launch kernel on host. + */ void PolishedRoughnessModel::step(CoreParams const& params, CoreStateHost& state) const { - launch_action(state, - this->make_executor( - params, state, PolishedRoughnessExecutorBuilder{})); + launch_action( + state, this->make_executor(params, state, PolishedRoughnessExecutor{})); } +//---------------------------------------------------------------------------// +/*! + * Launch kernel on device. + */ #if !CELER_USE_DEVICE void PolishedRoughnessModel::step(CoreParams const&, CoreStateDevice&) const { diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cu b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cu index 000cf8b441..c4d8846f9a 100644 --- a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cu +++ b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cu @@ -18,11 +18,14 @@ namespace celeritas namespace optical { //---------------------------------------------------------------------------// +/*! + * Launch kernel on device. + */ void PolishedRoughnessModel::step(CoreParams const& params, CoreStateDevice& state) const { - auto execute = this->make_executor( - params, state, PolishedRoughnessExecutorBuilder{}); + auto execute + = this->make_executor(params, state, PolishedRoughnessExecutor{}); static ActionLauncher const launch_kernel( *this); diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh b/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh index 90b0a6aa2f..d58d91fe11 100644 --- a/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh +++ b/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh @@ -14,21 +14,34 @@ namespace inp { struct NoRoughness; } + namespace optical { //---------------------------------------------------------------------------// /*! + * Polished roughness surface model. + * + * Trivial roughness model that just uses the global surface normal as the + * local facet normal. */ class PolishedRoughnessModel : public BuiltinRoughnessModel { public: + //!@{ + //! \name Type aliases using InputT = inp::NoRoughness; + //!@} + public: + // Construct model from surfaces and inputs PolishedRoughnessModel(SurfaceModelId model, std::vector surfaces, std::vector const&); + // Launch kernel on host void step(CoreParams const& params, CoreStateHost& state) const final; + + // Launch kernel on device void step(CoreParams const&, CoreStateDevice&) const final; }; diff --git a/src/celeritas/optical/surface/model/RoughnessApplier.hh b/src/celeritas/optical/surface/model/RoughnessApplier.hh index 6bbc4c6f41..7bf3a46330 100644 --- a/src/celeritas/optical/surface/model/RoughnessApplier.hh +++ b/src/celeritas/optical/surface/model/RoughnessApplier.hh @@ -15,11 +15,18 @@ namespace optical { //---------------------------------------------------------------------------// /*! + * Wrapper for surface roughness models. + * + * This wrapper determines the relevant roughness model and surface data for + * the track, and ensures that the normal being sampled from satisfies the + * entering surface convention. The roughness executor should return a functor + * that samples the facet normal given an RNG engine. */ template struct RoughnessApplier { - T const& executor_builder; + T const& make_sampler; + inline CELER_FUNCTION void operator()(CoreTrackView& track) const; }; @@ -27,6 +34,10 @@ struct RoughnessApplier // INLINE DEFINITIONS //---------------------------------------------------------------------------// /*! + * Sample and assign facet normal for the track. + * + * Ensures that the track's facet normal state field is updated with a facet + * normal following the entering surface convention. */ template CELER_FUNCTION void RoughnessApplier::operator()(CoreTrackView& track) const @@ -35,15 +46,22 @@ CELER_FUNCTION void RoughnessApplier::operator()(CoreTrackView& track) const auto model_view = track.surface_model(SurfacePhysicsOrder::roughness); auto rng = track.rng(); + // Ensure the local normal follows the entering surface convention auto normal = s_physics.global_normal(); if (model_view.direction() == SubsurfaceDirection::reverse) { normal = -normal; } - auto sample = executor_builder(model_view, track.geometry().dir(), normal); + CELER_ASSERT(is_entering_surface(track.geometry().dir(), normal)); + + // Construct normal sampler from executor + auto sample = make_sampler(model_view, track.geometry().dir(), normal); s_physics.facet_normal(sample(rng)); + + CELER_ENSURE( + is_entering_surface(track.geometry().dir(), s_physics.facet_normal())); } //---------------------------------------------------------------------------// diff --git a/src/celeritas/optical/surface/model/SmearRoughnessData.hh b/src/celeritas/optical/surface/model/SmearRoughnessData.hh index fea281e532..efba426f0a 100644 --- a/src/celeritas/optical/surface/model/SmearRoughnessData.hh +++ b/src/celeritas/optical/surface/model/SmearRoughnessData.hh @@ -17,12 +17,7 @@ namespace optical { //---------------------------------------------------------------------------// /*! - * Brief class description. - * - * Optional detailed class description, and possibly example usage: - * \code - SmearRoughnessData ...; - \endcode + * Storage for uniform smear roughness model data. */ template struct SmearRoughnessData diff --git a/src/celeritas/optical/surface/model/SmearRoughnessExecutor.hh b/src/celeritas/optical/surface/model/SmearRoughnessExecutor.hh index 9177bdeb1c..63881a62d3 100644 --- a/src/celeritas/optical/surface/model/SmearRoughnessExecutor.hh +++ b/src/celeritas/optical/surface/model/SmearRoughnessExecutor.hh @@ -16,11 +16,11 @@ namespace celeritas { namespace optical { - //---------------------------------------------------------------------------// /*! + * Construct a sampling executor for a smear roughness model. */ -struct SmearRoughnessExecutorBuilder +struct SmearRoughnessExecutor { //!@{ //! \name Type aliases @@ -29,15 +29,25 @@ struct SmearRoughnessExecutorBuilder NativeCRef data; - CELER_FUNCTION Sampler operator()(SurfaceModelView const& model, - Real3 const& dir, - Real3 const& normal) const - { - return Sampler( - dir, normal, data.roughness[model.internal_surface_id()]); - } + inline CELER_FUNCTION Sampler operator()(SurfaceModelView const& model, + Real3 const& dir, + Real3 const& normal) const; }; +//---------------------------------------------------------------------------// +// INLINE DEFINITIONS +//---------------------------------------------------------------------------// +/*! + * Construct sampler for the given model. + */ +CELER_FUNCTION auto +SmearRoughnessExecutor::operator()(SurfaceModelView const& model, + Real3 const& dir, + Real3 const& normal) const -> Sampler +{ + return Sampler(dir, normal, data.roughness[model.internal_surface_id()]); +} + //---------------------------------------------------------------------------// } // namespace optical } // namespace celeritas diff --git a/src/celeritas/optical/surface/model/SmearRoughnessModel.cc b/src/celeritas/optical/surface/model/SmearRoughnessModel.cc index 9ed6baf12c..edef055126 100644 --- a/src/celeritas/optical/surface/model/SmearRoughnessModel.cc +++ b/src/celeritas/optical/surface/model/SmearRoughnessModel.cc @@ -20,6 +20,9 @@ namespace celeritas namespace optical { //---------------------------------------------------------------------------// +/*! + * Construct model from surfaces and inputs. + */ SmearRoughnessModel::SmearRoughnessModel(SurfaceModelId model, std::vector surfaces, std::vector const& inputs) @@ -40,15 +43,22 @@ SmearRoughnessModel::SmearRoughnessModel(SurfaceModelId model, data_ = CollectionMirror{std::move(data)}; } +//---------------------------------------------------------------------------// +/*! + * Launch kernel on host. + */ void SmearRoughnessModel::step(CoreParams const& params, CoreStateHost& state) const { - launch_action( - state, - this->make_executor( - params, state, SmearRoughnessExecutorBuilder{data_.host_ref()})); + launch_action(state, + this->make_executor( + params, state, SmearRoughnessExecutor{data_.host_ref()})); } +//---------------------------------------------------------------------------// +/*! + * Launch kernel on device. + */ #if !CELER_USE_DEVICE void SmearRoughnessModel::step(CoreParams const&, CoreStateDevice&) const { diff --git a/src/celeritas/optical/surface/model/SmearRoughnessModel.cu b/src/celeritas/optical/surface/model/SmearRoughnessModel.cu index 3a610723d9..e96e5f7362 100644 --- a/src/celeritas/optical/surface/model/SmearRoughnessModel.cu +++ b/src/celeritas/optical/surface/model/SmearRoughnessModel.cu @@ -18,11 +18,14 @@ namespace celeritas namespace optical { //---------------------------------------------------------------------------// +/*! + * Launch kernel on device. + */ void SmearRoughnessModel::step(CoreParams const& params, CoreStateDevice& state) const { auto execute = this->make_executor( - params, state, SmearRoughnessExecutorBuilder{data_.device_ref()}); + params, state, SmearRoughnessExecutor{data_.device_ref()}); static ActionLauncher const launch_kernel( *this); diff --git a/src/celeritas/optical/surface/model/SmearRoughnessModel.hh b/src/celeritas/optical/surface/model/SmearRoughnessModel.hh index d0ca8d63bc..76125e2d3e 100644 --- a/src/celeritas/optical/surface/model/SmearRoughnessModel.hh +++ b/src/celeritas/optical/surface/model/SmearRoughnessModel.hh @@ -17,21 +17,34 @@ namespace inp { struct SmearRoughness; } + namespace optical { //---------------------------------------------------------------------------// /*! + * Smear roughness model. + * + * Approximates the surface roughness of an optical surface with the GliSur3 + * uniform smear roughness model. */ class SmearRoughnessModel : public BuiltinRoughnessModel { public: + //!@{ + //! \name Type aliases using InputT = inp::SmearRoughness; + //!@} + public: + // Construct model from surfaces and inputs SmearRoughnessModel(SurfaceModelId model, std::vector surfaces, std::vector const& inputs); + // Launch kernel on host void step(CoreParams const& params, CoreStateHost& state) const final; + + // Launch kernel on device void step(CoreParams const&, CoreStateDevice&) const final; private: diff --git a/src/celeritas/phys/SurfaceModel.hh b/src/celeritas/phys/SurfaceModel.hh index a1c196f0ef..518a75de5e 100644 --- a/src/celeritas/phys/SurfaceModel.hh +++ b/src/celeritas/phys/SurfaceModel.hh @@ -45,7 +45,7 @@ class SurfaceModel virtual ~SurfaceModel() = 0; //! Get the list of surfaces/layers this applies to - virtual VecSurfaceLayer get_surfaces() const = 0; + virtual VecSurfaceLayer const& get_surfaces() const = 0; //// ID/LABEL INTERFACE //// diff --git a/test/celeritas/phys/SurfacePhysicsMap.test.cc b/test/celeritas/phys/SurfacePhysicsMap.test.cc index 3c1f1b9188..846adb1aa0 100644 --- a/test/celeritas/phys/SurfacePhysicsMap.test.cc +++ b/test/celeritas/phys/SurfacePhysicsMap.test.cc @@ -33,7 +33,7 @@ class MockSurfaceModel final : public SurfaceModel { } - VecSurfaceLayer get_surfaces() const final { return surfaces_; } + VecSurfaceLayer const& get_surfaces() const final { return surfaces_; } private: VecSurfaceLayer surfaces_; From b0b4130c49baad9713082e74e49181ffba7aa208 Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Sat, 30 Aug 2025 00:04:55 -0500 Subject: [PATCH 11/22] Added builtin surface model builder --- .../surface/BuiltinSurfaceModelBuilder.hh | 194 ++++++++++++++++++ .../optical/surface/SurfacePhysicsParams.cc | 93 +-------- .../surface/model/BuiltinSurfaceModel.hh | 31 --- 3 files changed, 202 insertions(+), 116 deletions(-) create mode 100644 src/celeritas/optical/surface/BuiltinSurfaceModelBuilder.hh diff --git a/src/celeritas/optical/surface/BuiltinSurfaceModelBuilder.hh b/src/celeritas/optical/surface/BuiltinSurfaceModelBuilder.hh new file mode 100644 index 0000000000..246145fbcb --- /dev/null +++ b/src/celeritas/optical/surface/BuiltinSurfaceModelBuilder.hh @@ -0,0 +1,194 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/optical/surface/BuiltinSurfaceModelBuilder.hh +//---------------------------------------------------------------------------// +#pragma once + +#include + +#include "SurfaceModel.hh" +#include "model/BuiltinSurfaceModel.hh" + +namespace celeritas +{ +namespace optical +{ +namespace +{ +//---------------------------------------------------------------------------// +template<> +struct BuiltinApplier +{ + template + using Applier = TrivialApplier; +}; + +//---------------------------------------------------------------------------// +/*! + * Fake model as a placeholder for surface models yet to be implemented. + */ +template +class FakeModel : public BuiltinSurfaceModel +{ + public: + FakeModel(SurfaceModelId model_id, + std::string_view label, + std::vector surfaces) + : BuiltinSurfaceModel( + model_id, label, std::move(surfaces)) + { + } + + void step(CoreParams const&, CoreStateHost&) const final {} + void step(CoreParams const&, CoreStateDevice&) const final {} +}; + +//---------------------------------------------------------------------------// +/*! + * Build a fake model from input. + */ +template +std::shared_ptr> +fake_builtin_model_from_input(SurfaceModelId model_id, + std::string_view label, + std::map const& layer_map) +{ + std::vector surfaces; + for (auto const& [layer, input] : layer_map) + { + CELER_EXPECT(layer); + CELER_DISCARD(input); + surfaces.push_back(layer); + } + + CELER_ENSURE(surfaces.size() == layer_map.size()); + + return std::make_shared>(model_id, label, std::move(surfaces)); +} + +} // namespace + +//---------------------------------------------------------------------------// +/*! + * Utility for building built-in surface models from input data. + * + * Wraps the call to build a model with a check on whether the input data is + * empty. If empty, then the model is not built. Keeps track of number of + * models built and constructs new models with the next ID. + */ +class BuiltinSurfaceModelBuilder +{ + public: + //!@{ + //! \name Type aliases + using SPModel = std::shared_ptr; + //!@} + + public: + // Construct with storage to fill + inline BuiltinSurfaceModelBuilder(std::vector& models); + + // Construct a fake surface model + template + void build_fake(std::string_view label, std::map const&); + + // Construct a built-in surface model + template + void build(std::map const&); + + // Number of physics surfaces that have been constructed + size_type num_surfaces() const { return num_surf_; } + + private: + std::vector& models_; + size_type num_surf_{0}; + + // Construct built-in surface model from input + template + std::shared_ptr builtin_model_from_input( + SurfaceModelId, std::map const&); +}; + +//---------------------------------------------------------------------------// +// INLINE DEFINITIONS +//---------------------------------------------------------------------------// +/*! + * Construct with defaults. + */ +BuiltinSurfaceModelBuilder::BuiltinSurfaceModelBuilder( + std::vector& model) + : models_(model) +{ +} + +//---------------------------------------------------------------------------// +/*! + * Construct a built-in surface model. + * + * Only constructs and adds the surface model if the \c layer_map is not empty. + */ +template +void BuiltinSurfaceModelBuilder::build( + std::map const& layer_map) +{ + if (!layer_map.empty()) + { + models_.push_back(builtin_model_from_input( + SurfaceModelId(models_.size()), layer_map)); + num_surf_ += layer_map.size(); + } +} + +//---------------------------------------------------------------------------// +/*! + * Construct a fake surface model. + * + * A temporary utility to build fake surface models that have not yet been + * implemented. + */ +template +void BuiltinSurfaceModelBuilder::build_fake( + std::string_view label, std::map const& layer_map) +{ + if (!layer_map.empty()) + { + models_.push_back(fake_builtin_model_from_input( + SurfaceModelId(models_.size()), label, layer_map)); + num_surf_ += layer_map.size(); + } +} + +//---------------------------------------------------------------------------// +/*! + * Construct built-in model of type \c M from \c inp::SurfacePhysics surface + * layer map. + * + * The model \c M should have a type alias \c M::InputT which corresponds to + * the input type associated with each surface. + */ +template +std::shared_ptr BuiltinSurfaceModelBuilder::builtin_model_from_input( + SurfaceModelId model_id, + std::map const& layer_map) +{ + std::vector surfaces; + std::vector inputs; + + for (auto const& [surface, input] : layer_map) + { + CELER_ENSURE(surface); + surfaces.push_back(surface); + inputs.push_back(input); + } + + CELER_ENSURE(surfaces.size() == layer_map.size()); + CELER_ENSURE(inputs.size() == layer_map.size()); + + return std::make_shared(model_id, std::move(surfaces), inputs); +} + +//---------------------------------------------------------------------------// +} // namespace optical +} // namespace celeritas diff --git a/src/celeritas/optical/surface/SurfacePhysicsParams.cc b/src/celeritas/optical/surface/SurfacePhysicsParams.cc index 5702734bb0..82aefbc622 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsParams.cc +++ b/src/celeritas/optical/surface/SurfacePhysicsParams.cc @@ -11,6 +11,7 @@ #include "celeritas/inp/SurfacePhysics.hh" #include "celeritas/phys/SurfacePhysicsMapBuilder.hh" +#include "BuiltinSurfaceModelBuilder.hh" #include "model/GaussianRoughnessModel.hh" #include "model/PolishedRoughnessModel.hh" #include "model/SmearRoughnessModel.hh" @@ -21,84 +22,6 @@ namespace optical { namespace { -//---------------------------------------------------------------------------// -/*! - * A fake model used to mock actual surface physics models. - * - * TODO: Remove and replace with actual built-in surface models. - */ -template -class FakeModel : public SurfaceModel -{ - public: - FakeModel(SurfaceModelId model_id, - std::string_view label, - std::map const& layer_map) - : SurfaceModel(model_id, label) - { - for (auto const& [layer, data] : layer_map) - { - CELER_ENSURE(layer); - surfaces_.push_back(layer); - } - - CELER_ENSURE(layer_map.size() == surfaces_.size()); - } - - VecSurfaceLayer const& get_surfaces() const final { return surfaces_; } - - void step(CoreParams const&, CoreStateHost&) const final {} - void step(CoreParams const&, CoreStateDevice&) const final {} - - private: - std::vector surfaces_; -}; - -//---------------------------------------------------------------------------// -/*! - * Helper to build fake models. - * - * Doesn't insert empty models and keeps track of number of physics surfaces - * for validation purposes. - */ -class FakeModelBuilder -{ - public: - FakeModelBuilder(std::vector>& models) - : models_(models) - { - } - - template - void operator()(std::string_view label, - std::map const& layer_map) - { - if (!layer_map.empty()) - { - models_.push_back(std::make_shared>( - SurfaceModelId(models_.size()), label, layer_map)); - num_surf_ += layer_map.size(); - } - } - - template - void build(std::map const& layer_map) - { - if (!layer_map.empty()) - { - models_.push_back(builtin_model_from_input( - SurfaceModelId(models_.size()), layer_map)); - num_surf_ += layer_map.size(); - } - } - - size_type num_surfaces() const { return num_surf_; } - - private: - std::vector>& models_; - size_type num_surf_{0}; -}; - //---------------------------------------------------------------------------// /*! * Calculate number of physics surfaces as defined by interstitial materials. @@ -210,7 +133,7 @@ auto SurfacePhysicsParams::build_models( for (auto step : range(SurfacePhysicsOrder::size_)) { // Build fake models - FakeModelBuilder build_model{step_models[step]}; + BuiltinSurfaceModelBuilder build_model{step_models[step]}; switch (step) { case SurfacePhysicsOrder::roughness: @@ -221,14 +144,14 @@ auto SurfacePhysicsParams::build_models( input.roughness.gaussian); break; case SurfacePhysicsOrder::reflectivity: - build_model("grid", input.reflectivity.grid); - build_model("fresnel", input.reflectivity.fresnel); + build_model.build_fake("grid", input.reflectivity.grid); + build_model.build_fake("fresnel", input.reflectivity.fresnel); break; case SurfacePhysicsOrder::interaction: - build_model("dielectric-dielectric", - input.interaction.dielectric_dielectric); - build_model("dielectric-metal", - input.interaction.dielectric_metal); + build_model.build_fake("dielectric-dielectric", + input.interaction.dielectric_dielectric); + build_model.build_fake("dielectric-metal", + input.interaction.dielectric_metal); break; default: CELER_ASSERT_UNREACHABLE(); diff --git a/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh b/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh index 5d0498b013..49c8bd6754 100644 --- a/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh +++ b/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh @@ -134,37 +134,6 @@ auto BuiltinSurfaceModel::make_executor(CoreParams const& params, Applier{std::forward(exec)}); } -//---------------------------------------------------------------------------// -// FREE FUNCTIONS -//---------------------------------------------------------------------------// -/*! - * Construct built-in model of type \c M from \c inp::SurfacePhysics surface - * layer map. - * - * The model \c M should have a type alias \c M::InputT which corresponds to - * the input type associated with each surface. - */ -template -std::shared_ptr builtin_model_from_input( - SurfaceModelId model_id, - std::map const& layer_map) -{ - std::vector surfaces; - std::vector inputs; - - for (auto const& [surface, input] : layer_map) - { - CELER_ENSURE(surface); - surfaces.push_back(surface); - inputs.push_back(input); - } - - CELER_ENSURE(surfaces.size() == layer_map.size()); - CELER_ENSURE(inputs.size() == layer_map.size()); - - return std::make_shared(model_id, std::move(surfaces), inputs); -} - //---------------------------------------------------------------------------// // TEMPLATE ALIASES //---------------------------------------------------------------------------// From 8551827a399959aaf52297abccba1e2ed62c4c06 Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Sat, 30 Aug 2025 02:31:22 -0500 Subject: [PATCH 12/22] Added surface model view tests --- .../optical/surface/SurfaceModelView.hh | 33 ++-- .../optical/surface/SurfacePhysicsView.hh | 77 ++++++--- test/celeritas/optical/SurfacePhysics.test.cc | 161 +++++++++++++++--- 3 files changed, 209 insertions(+), 62 deletions(-) diff --git a/src/celeritas/optical/surface/SurfaceModelView.hh b/src/celeritas/optical/surface/SurfaceModelView.hh index 6ee23d13fa..65fb6f3e0a 100644 --- a/src/celeritas/optical/surface/SurfaceModelView.hh +++ b/src/celeritas/optical/surface/SurfaceModelView.hh @@ -29,9 +29,11 @@ class SurfaceModelView //!@} public: - // Construct from a direction and map view - inline CELER_FUNCTION - SurfaceModelView(SubsurfaceDirection, SurfacePhysicsMapView const&); + // Construct from a direction, map view, and materials + inline CELER_FUNCTION SurfaceModelView(SubsurfaceDirection, + SurfacePhysicsMapView, + OptMatId pre_mat, + OptMatId post_mat); // Get subsurface track direction inline CELER_FUNCTION SubsurfaceDirection direction() const; @@ -51,20 +53,25 @@ class SurfaceModelView private: SubsurfaceDirection dir_; SurfacePhysicsMapView physics_map_; - // OptMatId pre_material_; - // OptMatId post_material_; + OptMatId pre_material_; + OptMatId post_material_; }; //---------------------------------------------------------------------------// // INLINE DEFINITIONS //---------------------------------------------------------------------------// /*! - * Construct from track direction and physics map view. + * Construct from track direction, physics map view, and materials. */ CELER_FUNCTION SurfaceModelView::SurfaceModelView(SubsurfaceDirection dir, - SurfacePhysicsMapView const& physics_map) - : dir_(dir), physics_map_(physics_map) + SurfacePhysicsMapView physics_map, + OptMatId pre_material, + OptMatId post_material) + : dir_(dir) + , physics_map_(physics_map) + , pre_material_(pre_material) + , post_material_(post_material) { } @@ -74,7 +81,7 @@ SurfaceModelView::SurfaceModelView(SubsurfaceDirection dir, */ CELER_FUNCTION SubsurfaceDirection SurfaceModelView::direction() const { - return SubsurfaceDirection::forward; + return dir_; } //---------------------------------------------------------------------------// @@ -83,7 +90,7 @@ CELER_FUNCTION SubsurfaceDirection SurfaceModelView::direction() const */ CELER_FUNCTION SurfaceModelId SurfaceModelView::surface_model() const { - return {}; + return physics_map_.surface_model_id(); } //---------------------------------------------------------------------------// @@ -93,7 +100,7 @@ CELER_FUNCTION SurfaceModelId SurfaceModelView::surface_model() const CELER_FUNCTION auto SurfaceModelView::internal_surface_id() const -> InternalSurfaceId { - return {}; + return physics_map_.internal_surface_id(); } //---------------------------------------------------------------------------// @@ -102,7 +109,7 @@ CELER_FUNCTION auto SurfaceModelView::internal_surface_id() const */ CELER_FUNCTION OptMatId SurfaceModelView::pre_material() const { - return {}; + return pre_material_; } //---------------------------------------------------------------------------// @@ -111,7 +118,7 @@ CELER_FUNCTION OptMatId SurfaceModelView::pre_material() const */ CELER_FUNCTION OptMatId SurfaceModelView::post_material() const { - return {}; + return post_material_; } //---------------------------------------------------------------------------// diff --git a/src/celeritas/optical/surface/SurfacePhysicsView.hh b/src/celeritas/optical/surface/SurfacePhysicsView.hh index 932edfe147..e9e60645d1 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsView.hh +++ b/src/celeritas/optical/surface/SurfacePhysicsView.hh @@ -95,13 +95,6 @@ class SurfacePhysicsView // Number of valid positions of the track in the surface crossing inline CELER_FUNCTION SurfaceTrackPosition::size_type num_positions() const; - // Subsurface material of the current track position - inline CELER_FUNCTION OptMatId subsurface_material() const; - - // Next subsurface interface in the given direction (track-local) - inline CELER_FUNCTION - PhysSurfaceId subsurface_interface(SubsurfaceDirection) const; - // Calculate traversal direction from track momentum inline CELER_FUNCTION SubsurfaceDirection traversal_direction(Real3 const&) const; @@ -153,6 +146,17 @@ class SurfacePhysicsView template CELER_FUNCTION U to_record_index(SurfaceTrackPosition, ItemMap const&) const; + + // Subsurface material of the current track position + inline CELER_FUNCTION OptMatId subsurface_material() const; + inline CELER_FUNCTION + OptMatId subsurface_material(SubsurfaceDirection) const; + inline CELER_FUNCTION + OptMatId subsurface_material(SurfaceTrackPosition) const; + + // Next subsurface interface in the given direction (track-local) + inline CELER_FUNCTION + PhysSurfaceId subsurface_interface(SubsurfaceDirection) const; }; //---------------------------------------------------------------------------// @@ -333,25 +337,7 @@ SurfacePhysicsView::num_positions() const */ CELER_FUNCTION OptMatId SurfacePhysicsView::subsurface_material() const { - CELER_EXPECT(this->is_crossing_boundary()); - - if (this->in_pre_volume()) - { - return states_.pre_volume_material[track_id_]; - } - if (this->in_post_volume()) - { - return states_.post_volume_material[track_id_]; - } - - CELER_ASSERT(this->subsurface_position().get() > 0); - - auto material_record_id - = this->to_record_index(this->subsurface_position() - 1, - this->surface_record().subsurface_materials); - CELER_ASSERT(material_record_id < params_.subsurface_materials.size()); - - return params_.subsurface_materials[material_record_id]; + return this->subsurface_material(this->subsurface_position()); } //---------------------------------------------------------------------------// @@ -412,7 +398,10 @@ CELER_FUNCTION SurfaceModelView SurfacePhysicsView::surface_model( CELER_EXPECT(step != SurfacePhysicsOrder::size_); return SurfaceModelView{ - dir, this->surface_physics_map(step, this->subsurface_interface(dir))}; + dir, + this->surface_physics_map(step, this->subsurface_interface(dir)), + this->subsurface_material(), + this->subsurface_material(dir)}; } //---------------------------------------------------------------------------// @@ -513,6 +502,40 @@ CELER_FUNCTION U SurfacePhysicsView::to_record_index( return map[index]; } +//---------------------------------------------------------------------------// +CELER_FUNCTION OptMatId +SurfacePhysicsView::subsurface_material(SubsurfaceDirection dir) const +{ + return this->subsurface_material(this->subsurface_position() + + to_signed_offset(dir)); +} + +CELER_FUNCTION OptMatId +SurfacePhysicsView::subsurface_material(SurfaceTrackPosition pos) const +{ + CELER_EXPECT(this->is_crossing_boundary()); + + // In pre-volume + if (pos.get() == 0) + { + return states_.pre_volume_material[track_id_]; + } + // In post-volume + if (pos.get() + 1 == this->num_positions()) + { + return states_.post_volume_material[track_id_]; + } + + CELER_ASSERT(pos.get() > 0); + CELER_ASSERT(pos < this->num_positions() - 1); + + auto material_record_id = this->to_record_index( + pos - 1, this->surface_record().subsurface_materials); + CELER_ASSERT(material_record_id < params_.subsurface_materials.size()); + + return params_.subsurface_materials[material_record_id]; +} + //---------------------------------------------------------------------------// } // namespace optical } // namespace celeritas diff --git a/test/celeritas/optical/SurfacePhysics.test.cc b/test/celeritas/optical/SurfacePhysics.test.cc index d79cecad8c..5d07e02c78 100644 --- a/test/celeritas/optical/SurfacePhysics.test.cc +++ b/test/celeritas/optical/SurfacePhysics.test.cc @@ -6,6 +6,7 @@ //---------------------------------------------------------------------------// #include "celeritas/inp/SurfacePhysics.hh" +#include #include #include #include @@ -48,7 +49,7 @@ using namespace ::celeritas::test; template using SurfaceOrderArray = EnumArray; -using InternalSurfaceId = ::celeritas::SurfaceModel::InternalSurfaceId; +using InternalSurfaceId = SurfaceModel::InternalSurfaceId; auto constexpr forward = SubsurfaceDirection::forward; auto constexpr reverse = SubsurfaceDirection::reverse; @@ -74,8 +75,11 @@ struct SurfaceResult struct TraceResult { std::vector position{}; - std::vector material{}; - std::vector interface{}; + + SurfaceOrderArray> models; + SurfaceOrderArray> per_model_ids; + SurfaceOrderArray> pre_material; + SurfaceOrderArray> post_material; }; TraceResult trace_directions(SurfacePhysicsView& s_physics, @@ -84,16 +88,25 @@ TraceResult trace_directions(SurfacePhysicsView& s_physics, TraceResult result; result.position.push_back(s_physics.subsurface_position()); - result.material.push_back(s_physics.subsurface_material()); for (auto direction : directions) { - result.interface.push_back(s_physics.subsurface_interface(direction)); + for (auto step : range(SurfacePhysicsOrder::size_)) + { + auto surface_model = s_physics.surface_model(direction, step); + + EXPECT_EQ(direction, surface_model.direction()); + + result.models[step].push_back(surface_model.surface_model()); + result.per_model_ids[step].push_back( + surface_model.internal_surface_id()); + result.pre_material[step].push_back(surface_model.pre_material()); + result.post_material[step].push_back(surface_model.post_material()); + } s_physics.cross_subsurface_interface(direction); result.position.push_back(s_physics.subsurface_position()); - result.material.push_back(s_physics.subsurface_material()); } return result; @@ -484,12 +497,38 @@ TEST_F(SurfacePhysicsTest, traverse_subsurface) EXPECT_TRUE(s_physics.in_post_volume()); TraceResult expected{as_id_vec(0, 1), - as_id_vec(0, 1), - as_id_vec(6)}; + { + as_id_vec(0), + as_id_vec(1), + as_id_vec(0), + }, + { + as_id_vec(2), + as_id_vec(3), + as_id_vec(3), + }, + { + as_id_vec(0), + as_id_vec(0), + as_id_vec(0), + }, + { + as_id_vec(1), + as_id_vec(1), + as_id_vec(1), + }}; EXPECT_VEC_EQ(expected.position, result.position); - EXPECT_VEC_EQ(expected.material, result.material); - EXPECT_VEC_EQ(expected.interface, result.interface); + for (auto step : range(SurfacePhysicsOrder::size_)) + { + EXPECT_VEC_EQ(expected.models[step], result.models[step]); + EXPECT_VEC_EQ(expected.per_model_ids[step], + result.per_model_ids[step]); + EXPECT_VEC_EQ(expected.pre_material[step], + result.pre_material[step]); + EXPECT_VEC_EQ(expected.post_material[step], + result.post_material[step]); + } } { // Geometric surface 2 (reverse): B | A @@ -513,12 +552,38 @@ TEST_F(SurfacePhysicsTest, traverse_subsurface) EXPECT_TRUE(s_physics.in_post_volume()); TraceResult expected{as_id_vec(0, 1), - as_id_vec(1, 0), - as_id_vec(6)}; + { + as_id_vec(0), + as_id_vec(1), + as_id_vec(0), + }, + { + as_id_vec(2), + as_id_vec(3), + as_id_vec(3), + }, + { + as_id_vec(1), + as_id_vec(1), + as_id_vec(1), + }, + { + as_id_vec(0), + as_id_vec(0), + as_id_vec(0), + }}; EXPECT_VEC_EQ(expected.position, result.position); - EXPECT_VEC_EQ(expected.material, result.material); - EXPECT_VEC_EQ(expected.interface, result.interface); + for (auto step : range(SurfacePhysicsOrder::size_)) + { + EXPECT_VEC_EQ(expected.models[step], result.models[step]); + EXPECT_VEC_EQ(expected.per_model_ids[step], + result.per_model_ids[step]); + EXPECT_VEC_EQ(expected.pre_material[step], + result.pre_material[step]); + EXPECT_VEC_EQ(expected.post_material[step], + result.post_material[step]); + } } { // Geometric surface 0 (forward): A | D | B' | C | B @@ -552,12 +617,38 @@ TEST_F(SurfacePhysicsTest, traverse_subsurface) TraceResult expected{ as_id_vec(0, 1, 2, 1, 2, 3, 4, 3, 2, 1, 0), - as_id_vec(0, 3, 1, 3, 1, 2, 1, 2, 1, 3, 0), - as_id_vec(0, 1, 1, 1, 2, 3, 3, 2, 1, 0)}; + { + as_id_vec(0, 0, 0, 0, 1, 2, 2, 1, 0, 0), + as_id_vec(0, 1, 1, 1, 0, 1, 1, 0, 1, 0), + as_id_vec(0, 1, 1, 1, 1, 0, 0, 1, 1, 0), + }, + { + as_id_vec(0, 1, 1, 1, 0, 0, 0, 0, 1, 0), + as_id_vec(0, 0, 0, 0, 1, 1, 1, 1, 0, 0), + as_id_vec(0, 0, 0, 0, 1, 1, 1, 1, 0, 0), + }, + { + as_id_vec(0, 3, 1, 3, 1, 2, 1, 2, 1, 3), + as_id_vec(0, 3, 1, 3, 1, 2, 1, 2, 1, 3), + as_id_vec(0, 3, 1, 3, 1, 2, 1, 2, 1, 3), + }, + { + as_id_vec(3, 1, 3, 1, 2, 1, 2, 1, 3, 0), + as_id_vec(3, 1, 3, 1, 2, 1, 2, 1, 3, 0), + as_id_vec(3, 1, 3, 1, 2, 1, 2, 1, 3, 0), + }}; EXPECT_VEC_EQ(expected.position, result.position); - EXPECT_VEC_EQ(expected.material, result.material); - EXPECT_VEC_EQ(expected.interface, result.interface); + for (auto step : range(SurfacePhysicsOrder::size_)) + { + EXPECT_VEC_EQ(expected.models[step], result.models[step]); + EXPECT_VEC_EQ(expected.per_model_ids[step], + result.per_model_ids[step]); + EXPECT_VEC_EQ(expected.pre_material[step], + result.pre_material[step]); + EXPECT_VEC_EQ(expected.post_material[step], + result.post_material[step]); + } } { // Geometric surface 1 (reverse): B | C | A @@ -587,12 +678,38 @@ TEST_F(SurfacePhysicsTest, traverse_subsurface) TraceResult expected{ as_id_vec(0, 1, 2, 1, 0, 1, 2), - as_id_vec(1, 2, 0, 2, 1, 2, 0), - as_id_vec(5, 4, 4, 5, 5, 4)}; + { + as_id_vec(1, 2, 2, 1, 1, 2), + as_id_vec(0, 1, 1, 0, 0, 1), + as_id_vec(1, 0, 0, 1, 1, 0), + }, + { + as_id_vec(1, 1, 1, 1, 1, 1), + as_id_vec(2, 2, 2, 2, 2, 2), + as_id_vec(2, 2, 2, 2, 2, 2), + }, + { + as_id_vec(1, 2, 0, 2, 1, 2), + as_id_vec(1, 2, 0, 2, 1, 2), + as_id_vec(1, 2, 0, 2, 1, 2), + }, + { + as_id_vec(2, 0, 2, 1, 2, 0), + as_id_vec(2, 0, 2, 1, 2, 0), + as_id_vec(2, 0, 2, 1, 2, 0), + }}; EXPECT_VEC_EQ(expected.position, result.position); - EXPECT_VEC_EQ(expected.material, result.material); - EXPECT_VEC_EQ(expected.interface, result.interface); + for (auto step : range(SurfacePhysicsOrder::size_)) + { + EXPECT_VEC_EQ(expected.models[step], result.models[step]); + EXPECT_VEC_EQ(expected.per_model_ids[step], + result.per_model_ids[step]); + EXPECT_VEC_EQ(expected.pre_material[step], + result.pre_material[step]); + EXPECT_VEC_EQ(expected.post_material[step], + result.post_material[step]); + } } } From 89e572a86898710faea3da60cf597525a788c232 Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Sat, 30 Aug 2025 21:25:35 -0500 Subject: [PATCH 13/22] Cleanup surface physics view a bit --- .../optical/surface/SurfacePhysicsView.hh | 119 ++++++++---------- 1 file changed, 51 insertions(+), 68 deletions(-) diff --git a/src/celeritas/optical/surface/SurfacePhysicsView.hh b/src/celeritas/optical/surface/SurfacePhysicsView.hh index e9e60645d1..78426ec565 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsView.hh +++ b/src/celeritas/optical/surface/SurfacePhysicsView.hh @@ -18,6 +18,25 @@ namespace celeritas { namespace optical { + +namespace +{ +//---------------------------------------------------------------------------// +/*! + * Get the next track surface position in the given direction. + * + * Type-safe operation to ensure direction is only added in track-local frames. + * Uses unsigned underflow when moving reverse (dir = -1) while on a + * pre-surface (pos = 0) to wrap to an invalid position value. + */ +CELER_FORCEINLINE_FUNCTION SurfaceTrackPosition +operator+(SurfaceTrackPosition pos, SubsurfaceDirection dir) +{ + return pos + to_signed_offset(dir); +} + +} // namespace + //---------------------------------------------------------------------------// /*! * Optical surface physics data for a track. @@ -99,11 +118,6 @@ class SurfacePhysicsView inline CELER_FUNCTION SubsurfaceDirection traversal_direction(Real3 const&) const; - // Get surface model map for the given step and physics surface - inline CELER_FUNCTION - SurfacePhysicsMapView surface_physics_map(SurfacePhysicsOrder, - PhysSurfaceId) const; - // Get surface model for the given step inline CELER_FUNCTION SurfaceModelView surface_model(SubsurfaceDirection, @@ -147,10 +161,7 @@ class SurfacePhysicsView CELER_FUNCTION U to_record_index(SurfaceTrackPosition, ItemMap const&) const; - // Subsurface material of the current track position - inline CELER_FUNCTION OptMatId subsurface_material() const; - inline CELER_FUNCTION - OptMatId subsurface_material(SubsurfaceDirection) const; + // Subsurface material at the given position inline CELER_FUNCTION OptMatId subsurface_material(SurfaceTrackPosition) const; @@ -265,8 +276,7 @@ CELER_FUNCTION bool SurfacePhysicsView::is_exiting(SubsurfaceDirection d) const CELER_EXPECT(this->is_crossing_boundary()); // Use unsigned underflow when moving reverse (-1) on the pre-surface // (position 0) to wrap to an invalid position value - return static_cast(this->subsurface_position().get() - + to_signed_offset(d)) + return (this->subsurface_position() + d).unchecked_get() >= this->num_positions(); } @@ -331,34 +341,6 @@ SurfacePhysicsView::num_positions() const return this->surface_record().subsurface_materials.size() + 2; } -//---------------------------------------------------------------------------// -/*! - * Return the subsurface material ID of the current track position. - */ -CELER_FUNCTION OptMatId SurfacePhysicsView::subsurface_material() const -{ - return this->subsurface_material(this->subsurface_position()); -} - -//---------------------------------------------------------------------------// -/*! - * Get the physics surface ID of the subsurface in the given direction. - */ -CELER_FUNCTION PhysSurfaceId -SurfacePhysicsView::subsurface_interface(SubsurfaceDirection d) const -{ - CELER_EXPECT(this->is_crossing_boundary()); - CELER_EXPECT(!this->is_exiting(d)); - - auto track_pos = this->subsurface_position(); - if (d == SubsurfaceDirection::reverse) - { - --track_pos; - } - return this->to_record_index(track_pos, - this->surface_record().subsurface_interfaces); -} - //---------------------------------------------------------------------------// /*! * Calculate traversal direction from track momentum. @@ -372,20 +354,6 @@ SurfacePhysicsView::traversal_direction(Real3 const& dir) const is_entering_surface(dir, this->global_normal())); } -//---------------------------------------------------------------------------// -/*! - * Get surface model map for the given step and physics surface - */ -CELER_FUNCTION SurfacePhysicsMapView SurfacePhysicsView::surface_physics_map( - SurfacePhysicsOrder step, PhysSurfaceId surface) const -{ - CELER_EXPECT(this->is_crossing_boundary()); - CELER_EXPECT(surface); - CELER_EXPECT(step != SurfacePhysicsOrder::size_); - - return SurfacePhysicsMapView{params_.model_maps[step], surface}; -} - //---------------------------------------------------------------------------// /*! * Get surface model view of the given step in the given direction. @@ -397,11 +365,14 @@ CELER_FUNCTION SurfaceModelView SurfacePhysicsView::surface_model( CELER_EXPECT(!this->is_exiting(dir)); CELER_EXPECT(step != SurfacePhysicsOrder::size_); + auto phys_surface = this->subsurface_interface(dir); + CELER_ASSERT(phys_surface); + return SurfaceModelView{ dir, - this->surface_physics_map(step, this->subsurface_interface(dir)), - this->subsurface_material(), - this->subsurface_material(dir)}; + SurfacePhysicsMapView{params_.model_maps[step], phys_surface}, + this->subsurface_material(this->subsurface_position()), + this->subsurface_material(this->subsurface_position() + dir)}; } //---------------------------------------------------------------------------// @@ -434,8 +405,7 @@ SurfacePhysicsView::cross_subsurface_interface(SubsurfaceDirection d) { CELER_EXPECT(this->is_crossing_boundary()); CELER_EXPECT(!this->is_exiting(d)); - this->subsurface_position(this->subsurface_position() - + to_signed_offset(d)); + this->subsurface_position(this->subsurface_position() + d); } //---------------------------------------------------------------------------// @@ -497,37 +467,35 @@ CELER_FUNCTION U SurfacePhysicsView::to_record_index( { index = T{map.size() - 1 - index.get()}; } + CELER_ASSERT(index < map.size()); return map[index]; } //---------------------------------------------------------------------------// -CELER_FUNCTION OptMatId -SurfacePhysicsView::subsurface_material(SubsurfaceDirection dir) const -{ - return this->subsurface_material(this->subsurface_position() - + to_signed_offset(dir)); -} - +/*! + * Return the subsurface material ID of the current track position. + */ CELER_FUNCTION OptMatId SurfacePhysicsView::subsurface_material(SurfaceTrackPosition pos) const { CELER_EXPECT(this->is_crossing_boundary()); + auto pos_range = range(SurfaceTrackPosition{this->num_positions()}); + // In pre-volume - if (pos.get() == 0) + if (pos == pos_range.front()) { return states_.pre_volume_material[track_id_]; } // In post-volume - if (pos.get() + 1 == this->num_positions()) + if (pos == pos_range.back()) { return states_.post_volume_material[track_id_]; } CELER_ASSERT(pos.get() > 0); - CELER_ASSERT(pos < this->num_positions() - 1); auto material_record_id = this->to_record_index( pos - 1, this->surface_record().subsurface_materials); @@ -536,6 +504,21 @@ SurfacePhysicsView::subsurface_material(SurfaceTrackPosition pos) const return params_.subsurface_materials[material_record_id]; } +//---------------------------------------------------------------------------// +/*! + * Get the physics surface ID of the subsurface in the given direction. + */ +CELER_FUNCTION PhysSurfaceId +SurfacePhysicsView::subsurface_interface(SubsurfaceDirection d) const +{ + CELER_EXPECT(this->is_crossing_boundary()); + CELER_EXPECT(!this->is_exiting(d)); + + auto track_pos = this->subsurface_position() + (static_cast(d) - 1); + return this->to_record_index(track_pos, + this->surface_record().subsurface_interfaces); +} + //---------------------------------------------------------------------------// } // namespace optical } // namespace celeritas From 4ff7fa4301e85dc74344b66535b2727d2962d625 Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Tue, 2 Sep 2025 11:49:42 -0500 Subject: [PATCH 14/22] Pre PR clean up --- src/celeritas/optical/CoreParams.cc | 10 ---------- src/celeritas/optical/CoreTrackView.hh | 1 - .../optical/surface/SurfacePhysicsParams.hh | 12 ------------ .../optical/surface/detail/InitBoundaryExecutor.hh | 12 ------------ 4 files changed, 35 deletions(-) diff --git a/src/celeritas/optical/CoreParams.cc b/src/celeritas/optical/CoreParams.cc index 4122887587..d26e66fb1b 100644 --- a/src/celeritas/optical/CoreParams.cc +++ b/src/celeritas/optical/CoreParams.cc @@ -112,16 +112,6 @@ CoreParams::CoreParams(Input&& input) : input_(std::move(input)) CELER_EXPECT(input_); - CELER_LOG_LOCAL(info) << " number of geometric surfaces: " - << input_.surface->num_surfaces(); - CELER_LOG_LOCAL(info) << " number of surfaces + default: " - << input_.surface_physics->num_surfaces(); - CELER_LOG_LOCAL(info) << " default surface: " - << input_.surface_physics->default_surface().get(); - - CELER_EXPECT(input_.surface->num_surfaces() + 1 - == input_.surface_physics->num_surfaces()); - // TODO: provide detectors in input, passing from core params detectors_ = input_.detectors; if (!detectors_) diff --git a/src/celeritas/optical/CoreTrackView.hh b/src/celeritas/optical/CoreTrackView.hh index 6910fc6e57..436929e828 100644 --- a/src/celeritas/optical/CoreTrackView.hh +++ b/src/celeritas/optical/CoreTrackView.hh @@ -243,7 +243,6 @@ CELER_FUNCTION auto CoreTrackView::surface_model(SurfacePhysicsOrder step) const { auto s_physics = this->surface_physics(); CELER_EXPECT(s_physics.is_crossing_boundary()); - CELER_EXPECT(is_soft_unit_vector(this->geometry().dir())); return s_physics.surface_model( s_physics.traversal_direction(this->geometry().dir()), step); diff --git a/src/celeritas/optical/surface/SurfacePhysicsParams.hh b/src/celeritas/optical/surface/SurfacePhysicsParams.hh index 995565eb5f..89ad02233b 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsParams.hh +++ b/src/celeritas/optical/surface/SurfacePhysicsParams.hh @@ -93,18 +93,6 @@ class SurfacePhysicsParams final return models_[step]; } - //! Number of geometric surfaces (including default surface) - SurfaceId::size_type num_surfaces() const - { - return data_.host_ref().surfaces.size(); - } - - //! Default surface ID - SurfaceId default_surface() const - { - return data_.host_ref().scalars.default_surface; - } - private: // Boundary actions std::shared_ptr init_boundary_action_; diff --git a/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh b/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh index 3940c458f3..83ef20b7c7 100644 --- a/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh +++ b/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh @@ -90,18 +90,6 @@ CELER_FUNCTION void InitBoundaryExecutor::operator()(CoreTrackView& track) const oriented_surface.orientation = SubsurfaceDirection::forward; } -#if !CELER_DEVICE_COMPILE - if (!is_soft_unit_vector(track.geometry().dir())) - { - CELER_LOG_LOCAL(error) - << " track surface: " - << track.surface_physics().surface().unchecked_get() - << " (invalid: " << SurfaceId{}.unchecked_get() - << ", is_crossing_boundary: " - << track.surface_physics().is_crossing_boundary() << ")"; - } -#endif - surface_physics = SurfacePhysicsView::Initializer{oriented_surface.surface, oriented_surface.orientation, From 9e2a05f242e1a20a29d51b25a4201b0ee932415a Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Tue, 2 Sep 2025 12:15:06 -0500 Subject: [PATCH 15/22] Revert sincos change in GaussianRoughnessSampler --- src/celeritas/optical/surface/GaussianRoughnessSampler.hh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/celeritas/optical/surface/GaussianRoughnessSampler.hh b/src/celeritas/optical/surface/GaussianRoughnessSampler.hh index a3abdf110d..2277101888 100644 --- a/src/celeritas/optical/surface/GaussianRoughnessSampler.hh +++ b/src/celeritas/optical/surface/GaussianRoughnessSampler.hh @@ -103,9 +103,7 @@ CELER_FUNCTION Real3 GaussianRoughnessSampler::operator()(Engine& rng) // nonpositive slope are generally vanishingly small) alpha = std::fabs(sample_alpha_(rng)); } while (alpha >= alpha_max_); - sin_alpha = std::sin(alpha); - cos_alpha = std::cos(alpha); - // sincos(alpha, &sin_alpha, &cos_alpha); + sincos(alpha, &sin_alpha, &cos_alpha); // Transform to polar angle using rejection } while (RejectionSampler{sin_alpha, f_max_}(rng)); From 966f24fff5e50c7d48f22ae67b62669105683782 Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Tue, 9 Sep 2025 07:34:34 -0500 Subject: [PATCH 16/22] Added Seth's changes --- src/celeritas/optical/CoreTrackView.hh | 18 ------------- .../optical/action/ActionLauncher.device.hh | 27 ++++++++++--------- .../optical/surface/SurfacePhysicsParams.cc | 5 ++-- .../optical/surface/SurfacePhysicsView.hh | 19 +++++++++++++ .../optical/surface/TrackSlotExecutor.hh | 5 +++- .../BuiltinSurfaceModelBuilder.hh | 14 +++++----- .../surface/detail/InitBoundaryExecutor.hh | 10 ++++++- .../surface/model/BuiltinSurfaceModel.hh | 6 +---- .../surface/model/GaussianRoughnessModel.cu | 3 +-- .../surface/model/PolishedRoughnessModel.cu | 3 +-- .../optical/surface/model/RoughnessApplier.hh | 11 ++++---- .../surface/model/SmearRoughnessModel.cu | 3 +-- 12 files changed, 68 insertions(+), 56 deletions(-) rename src/celeritas/optical/surface/{ => detail}/BuiltinSurfaceModelBuilder.hh (95%) diff --git a/src/celeritas/optical/CoreTrackView.hh b/src/celeritas/optical/CoreTrackView.hh index 436929e828..4198ff924c 100644 --- a/src/celeritas/optical/CoreTrackView.hh +++ b/src/celeritas/optical/CoreTrackView.hh @@ -75,10 +75,6 @@ class CoreTrackView // Return a surface physics view inline CELER_FUNCTION SurfacePhysicsView surface_physics() const; - // Return a surface model view for the given step - inline CELER_FUNCTION - SurfaceModelView surface_model(SurfacePhysicsOrder) const; - // Return an RNG engine inline CELER_FUNCTION RngEngine rng() const; @@ -234,20 +230,6 @@ CELER_FUNCTION auto CoreTrackView::surface_physics() const -> SurfacePhysicsView this->track_slot_id()}; } -//---------------------------------------------------------------------------// -/*! - * Return a surface model view for the given step. - */ -CELER_FUNCTION auto CoreTrackView::surface_model(SurfacePhysicsOrder step) const - -> SurfaceModelView -{ - auto s_physics = this->surface_physics(); - CELER_EXPECT(s_physics.is_crossing_boundary()); - - return s_physics.surface_model( - s_physics.traversal_direction(this->geometry().dir()), step); -} - //---------------------------------------------------------------------------// /*! * Return the RNG engine. diff --git a/src/celeritas/optical/action/ActionLauncher.device.hh b/src/celeritas/optical/action/ActionLauncher.device.hh index da184d875d..f0ecbd6d86 100644 --- a/src/celeritas/optical/action/ActionLauncher.device.hh +++ b/src/celeritas/optical/action/ActionLauncher.device.hh @@ -44,7 +44,7 @@ namespace optical } * \endcode */ -template +template class ActionLauncher : public KernelLauncher { static_assert( @@ -52,16 +52,17 @@ class ActionLauncher : public KernelLauncher || CELER_COMPILER == CELER_COMPILER_CLANG) && !std::is_pointer_v && !std::is_reference_v, R"(Launched action must be a trivially copyable function object)"); - // using StepActionT = OpticalStepActionInterface; public: // Create a launcher from a string using KernelLauncher::KernelLauncher; // Create a launcher from an action + template explicit ActionLauncher(StepActionT const& action); // Create a launcher with a string extension + template ActionLauncher(StepActionT const& action, std::string_view ext); // Launch a kernel for a thread range or number of threads @@ -76,9 +77,10 @@ class ActionLauncher : public KernelLauncher /*! * Create a launcher from an action. */ -template -ActionLauncher::ActionLauncher(StepActionT const& action) - : ActionLauncher{action.label()} +template +template +ActionLauncher::ActionLauncher(StepActionT const& action) + : KernelLauncher{action.label()} { } @@ -86,10 +88,11 @@ ActionLauncher::ActionLauncher(StepActionT const& action) /*! * Create a launcher with a string extension. */ -template -ActionLauncher::ActionLauncher(StepActionT const& action, - std::string_view ext) - : ActionLauncher{std::string(action.label()) + "-" + std::string(ext)} +template +template +ActionLauncher::ActionLauncher(StepActionT const& action, + std::string_view ext) + : KernelLauncher{std::string(action.label()) + "-" + std::string(ext)} { } @@ -97,9 +100,9 @@ ActionLauncher::ActionLauncher(StepActionT const& action, /*! * Launch a kernel for the wrapped executor. */ -template -void ActionLauncher::operator()( - CoreState const& state, F const& call_thread) const +template +void ActionLauncher::operator()(CoreState const& state, + F const& call_thread) const { return (*this)( range(ThreadId{state.size()}), state.stream_id(), call_thread); diff --git a/src/celeritas/optical/surface/SurfacePhysicsParams.cc b/src/celeritas/optical/surface/SurfacePhysicsParams.cc index 82aefbc622..78f69dbf34 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsParams.cc +++ b/src/celeritas/optical/surface/SurfacePhysicsParams.cc @@ -11,11 +11,12 @@ #include "celeritas/inp/SurfacePhysics.hh" #include "celeritas/phys/SurfacePhysicsMapBuilder.hh" -#include "BuiltinSurfaceModelBuilder.hh" #include "model/GaussianRoughnessModel.hh" #include "model/PolishedRoughnessModel.hh" #include "model/SmearRoughnessModel.hh" +#include "detail/BuiltinSurfaceModelBuilder.hh" + namespace celeritas { namespace optical @@ -133,7 +134,7 @@ auto SurfacePhysicsParams::build_models( for (auto step : range(SurfacePhysicsOrder::size_)) { // Build fake models - BuiltinSurfaceModelBuilder build_model{step_models[step]}; + detail::BuiltinSurfaceModelBuilder build_model{step_models[step]}; switch (step) { case SurfacePhysicsOrder::roughness: diff --git a/src/celeritas/optical/surface/SurfacePhysicsView.hh b/src/celeritas/optical/surface/SurfacePhysicsView.hh index 78426ec565..59d3b9c539 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsView.hh +++ b/src/celeritas/optical/surface/SurfacePhysicsView.hh @@ -123,6 +123,10 @@ class SurfacePhysicsView SurfaceModelView surface_model(SubsurfaceDirection, SurfacePhysicsOrder) const; + // Get surface model for the given step + inline CELER_FUNCTION SurfaceModelView + surface_model(Real3 const&, SurfacePhysicsOrder) const; + // Get local facet normal inline CELER_FUNCTION Real3 const& facet_normal() const; @@ -375,6 +379,21 @@ CELER_FUNCTION SurfaceModelView SurfacePhysicsView::surface_model( this->subsurface_material(this->subsurface_position() + dir)}; } +//---------------------------------------------------------------------------// +/*! + * Get surface model view of the given step for a track moving in the given + * direction. + * + * Helper function that determines the traversal direction from the track + * direction and constructs a surface model from it. + */ +CELER_FUNCTION SurfaceModelView SurfacePhysicsView::surface_model( + Real3 const& dir, SurfacePhysicsOrder step) const +{ + CELER_EXPECT(this->is_crossing_boundary()); + return this->surface_model(this->traversal_direction(dir), step); +} + //---------------------------------------------------------------------------// /*! * Get local facet normal after roughness sampling. diff --git a/src/celeritas/optical/surface/TrackSlotExecutor.hh b/src/celeritas/optical/surface/TrackSlotExecutor.hh index 7a3513080e..aa1122dad8 100644 --- a/src/celeritas/optical/surface/TrackSlotExecutor.hh +++ b/src/celeritas/optical/surface/TrackSlotExecutor.hh @@ -27,7 +27,10 @@ struct IsSurfaceModelEqual CELER_FUNCTION bool operator()(CoreTrackView const& track) const { return track.surface_physics().is_crossing_boundary() - && track.surface_model(step).surface_model() == model; + && track.surface_physics() + .surface_model(track.geometry().dir(), step) + .surface_model() + == model; } }; diff --git a/src/celeritas/optical/surface/BuiltinSurfaceModelBuilder.hh b/src/celeritas/optical/surface/detail/BuiltinSurfaceModelBuilder.hh similarity index 95% rename from src/celeritas/optical/surface/BuiltinSurfaceModelBuilder.hh rename to src/celeritas/optical/surface/detail/BuiltinSurfaceModelBuilder.hh index 246145fbcb..211d700ada 100644 --- a/src/celeritas/optical/surface/BuiltinSurfaceModelBuilder.hh +++ b/src/celeritas/optical/surface/detail/BuiltinSurfaceModelBuilder.hh @@ -2,21 +2,18 @@ // Copyright Celeritas contributors: see top-level COPYRIGHT file for details // SPDX-License-Identifier: (Apache-2.0 OR MIT) //---------------------------------------------------------------------------// -//! \file celeritas/optical/surface/BuiltinSurfaceModelBuilder.hh +//! \file celeritas/optical/surface/detail/BuiltinSurfaceModelBuilder.hh //---------------------------------------------------------------------------// #pragma once #include -#include "SurfaceModel.hh" -#include "model/BuiltinSurfaceModel.hh" +#include "celeritas/optical/surface/model/BuiltinSurfaceModel.hh" namespace celeritas { namespace optical { -namespace -{ //---------------------------------------------------------------------------// template<> struct BuiltinApplier @@ -25,6 +22,10 @@ struct BuiltinApplier using Applier = TrivialApplier; }; +namespace detail +{ +namespace +{ //---------------------------------------------------------------------------// /*! * Fake model as a placeholder for surface models yet to be implemented. @@ -88,7 +89,7 @@ class BuiltinSurfaceModelBuilder public: // Construct with storage to fill - inline BuiltinSurfaceModelBuilder(std::vector& models); + explicit inline BuiltinSurfaceModelBuilder(std::vector& models); // Construct a fake surface model template @@ -190,5 +191,6 @@ std::shared_ptr BuiltinSurfaceModelBuilder::builtin_model_from_input( } //---------------------------------------------------------------------------// +} // namespace detail } // namespace optical } // namespace celeritas diff --git a/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh b/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh index 83ef20b7c7..6581496679 100644 --- a/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh +++ b/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh @@ -90,10 +90,18 @@ CELER_FUNCTION void InitBoundaryExecutor::operator()(CoreTrackView& track) const oriented_surface.orientation = SubsurfaceDirection::forward; } + // Enforce surface normal convention, swapping normal if geometry returns + // one not entering the surface + Real3 global_normal = geo.normal(); + if (!is_entering_surface(geo.dir(), global_normal)) + { + global_normal = -global_normal; + } + surface_physics = SurfacePhysicsView::Initializer{oriented_surface.surface, oriented_surface.orientation, - geo.normal(), + global_normal, pre_volume_material, post_volume_material}; diff --git a/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh b/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh index 49c8bd6754..f727c23774 100644 --- a/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh +++ b/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh @@ -17,8 +17,6 @@ namespace celeritas { namespace optical { -namespace -{ //---------------------------------------------------------------------------// /*! * Trivial applier which just forwards the track to the executor. @@ -62,8 +60,6 @@ struct BuiltinApplier using Applier = TrivialApplier; }; -} // namespace - //---------------------------------------------------------------------------// /*! * Templated base class for built-in optical surface physics models. @@ -80,7 +76,7 @@ class BuiltinSurfaceModel : public SurfaceModel //!@{ //! \name Type aliases template - using Applier = typename BuiltinApplier::Applier; + using Applier = typename BuiltinApplier::template Applier; //!@} public: diff --git a/src/celeritas/optical/surface/model/GaussianRoughnessModel.cu b/src/celeritas/optical/surface/model/GaussianRoughnessModel.cu index 107c0bab6c..79f4125a71 100644 --- a/src/celeritas/optical/surface/model/GaussianRoughnessModel.cu +++ b/src/celeritas/optical/surface/model/GaussianRoughnessModel.cu @@ -27,8 +27,7 @@ void GaussianRoughnessModel::step(CoreParams const& params, auto execute = this->make_executor( params, state, GaussianRoughnessExecutor{data_.device_ref()}); - static ActionLauncher const launch_kernel( - *this); + static ActionLauncher const launch_kernel(*this); launch_kernel(state, execute); } diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cu b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cu index c4d8846f9a..0a6a003389 100644 --- a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cu +++ b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cu @@ -27,8 +27,7 @@ void PolishedRoughnessModel::step(CoreParams const& params, auto execute = this->make_executor(params, state, PolishedRoughnessExecutor{}); - static ActionLauncher const launch_kernel( - *this); + static ActionLauncher const launch_kernel(*this); launch_kernel(state, execute); } diff --git a/src/celeritas/optical/surface/model/RoughnessApplier.hh b/src/celeritas/optical/surface/model/RoughnessApplier.hh index 7bf3a46330..8ced3e683e 100644 --- a/src/celeritas/optical/surface/model/RoughnessApplier.hh +++ b/src/celeritas/optical/surface/model/RoughnessApplier.hh @@ -42,8 +42,10 @@ struct RoughnessApplier template CELER_FUNCTION void RoughnessApplier::operator()(CoreTrackView& track) const { + auto const& track_dir = track.geometry().dir(); auto s_physics = track.surface_physics(); - auto model_view = track.surface_model(SurfacePhysicsOrder::roughness); + auto model_view + = s_physics.surface_model(track_dir, SurfacePhysicsOrder::roughness); auto rng = track.rng(); // Ensure the local normal follows the entering surface convention @@ -53,15 +55,14 @@ CELER_FUNCTION void RoughnessApplier::operator()(CoreTrackView& track) const normal = -normal; } - CELER_ASSERT(is_entering_surface(track.geometry().dir(), normal)); + CELER_ASSERT(is_entering_surface(track_dir, normal)); // Construct normal sampler from executor - auto sample = make_sampler(model_view, track.geometry().dir(), normal); + auto sample = make_sampler(model_view, track_dir, normal); s_physics.facet_normal(sample(rng)); - CELER_ENSURE( - is_entering_surface(track.geometry().dir(), s_physics.facet_normal())); + CELER_ENSURE(is_entering_surface(track_dir, s_physics.facet_normal())); } //---------------------------------------------------------------------------// diff --git a/src/celeritas/optical/surface/model/SmearRoughnessModel.cu b/src/celeritas/optical/surface/model/SmearRoughnessModel.cu index e96e5f7362..6122785a9f 100644 --- a/src/celeritas/optical/surface/model/SmearRoughnessModel.cu +++ b/src/celeritas/optical/surface/model/SmearRoughnessModel.cu @@ -27,8 +27,7 @@ void SmearRoughnessModel::step(CoreParams const& params, auto execute = this->make_executor( params, state, SmearRoughnessExecutor{data_.device_ref()}); - static ActionLauncher const launch_kernel( - *this); + static ActionLauncher const launch_kernel(*this); launch_kernel(state, execute); } From 29b5a25cab4ad700ef4c085d52baf442f1ed76cd Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Tue, 9 Sep 2025 11:29:19 -0500 Subject: [PATCH 17/22] Fix failing tests --- src/celeritas/optical/surface/GaussianRoughnessSampler.hh | 2 +- src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/celeritas/optical/surface/GaussianRoughnessSampler.hh b/src/celeritas/optical/surface/GaussianRoughnessSampler.hh index 2277101888..0d2c59ad7f 100644 --- a/src/celeritas/optical/surface/GaussianRoughnessSampler.hh +++ b/src/celeritas/optical/surface/GaussianRoughnessSampler.hh @@ -103,7 +103,7 @@ CELER_FUNCTION Real3 GaussianRoughnessSampler::operator()(Engine& rng) // nonpositive slope are generally vanishingly small) alpha = std::fabs(sample_alpha_(rng)); } while (alpha >= alpha_max_); - sincos(alpha, &sin_alpha, &cos_alpha); + ::sincos(alpha, &sin_alpha, &cos_alpha); // Transform to polar angle using rejection } while (RejectionSampler{sin_alpha, f_max_}(rng)); diff --git a/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh b/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh index 6581496679..c76df98956 100644 --- a/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh +++ b/src/celeritas/optical/surface/detail/InitBoundaryExecutor.hh @@ -8,6 +8,7 @@ #include "corecel/Assert.hh" #include "corecel/Macros.hh" +#include "corecel/math/ArrayOperators.hh" #include "celeritas/geo/GeoTrackView.hh" #include "celeritas/optical/CoreTrackView.hh" #include "celeritas/optical/SimTrackView.hh" From cfddbbfc8af6c3216acc980890165bb9de36ce06 Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Thu, 11 Sep 2025 05:20:55 -0500 Subject: [PATCH 18/22] Reverted sincos using global namespace --- src/celeritas/optical/surface/GaussianRoughnessSampler.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/celeritas/optical/surface/GaussianRoughnessSampler.hh b/src/celeritas/optical/surface/GaussianRoughnessSampler.hh index 0d2c59ad7f..2277101888 100644 --- a/src/celeritas/optical/surface/GaussianRoughnessSampler.hh +++ b/src/celeritas/optical/surface/GaussianRoughnessSampler.hh @@ -103,7 +103,7 @@ CELER_FUNCTION Real3 GaussianRoughnessSampler::operator()(Engine& rng) // nonpositive slope are generally vanishingly small) alpha = std::fabs(sample_alpha_(rng)); } while (alpha >= alpha_max_); - ::sincos(alpha, &sin_alpha, &cos_alpha); + sincos(alpha, &sin_alpha, &cos_alpha); // Transform to polar angle using rejection } while (RejectionSampler{sin_alpha, f_max_}(rng)); From 7941d4395f6579ea31883bf136300f9db5051242 Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Thu, 18 Sep 2025 10:00:57 -0500 Subject: [PATCH 19/22] Added some of Seth's minor suggestions --- .../optical/surface/SurfacePhysicsUtils.hh | 23 ++++++++- .../optical/surface/SurfacePhysicsView.hh | 47 +++---------------- .../optical/surface/TrackSlotExecutor.hh | 8 ++-- .../surface/model/GaussianRoughnessModel.cc | 2 +- .../optical/surface/model/RoughnessApplier.hh | 3 +- .../surface/model/SmearRoughnessModel.cc | 2 +- 6 files changed, 37 insertions(+), 48 deletions(-) diff --git a/src/celeritas/optical/surface/SurfacePhysicsUtils.hh b/src/celeritas/optical/surface/SurfacePhysicsUtils.hh index 384bf7299f..7ab0095e6a 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsUtils.hh +++ b/src/celeritas/optical/surface/SurfacePhysicsUtils.hh @@ -8,12 +8,18 @@ #include "corecel/math/Algorithms.hh" #include "corecel/math/ArrayUtils.hh" -#include "celeritas/Types.hh" +#include "celeritas/optical/Types.hh" namespace celeritas { namespace optical { +//---------------------------------------------------------------------------// +// TYPE ALIASES +//---------------------------------------------------------------------------// + +using SurfaceTrackPosition = OpaqueId; + //---------------------------------------------------------------------------// /*! * Whether a track is entering the surface defined by the given normal. @@ -28,6 +34,21 @@ is_entering_surface(Real3 const& dir, Real3 const& normal) return dot_product(dir, normal) < 0; } +//---------------------------------------------------------------------------// +/*! + * Get the next track surface position in the given direction. + * + * Type-safe operation to ensure direction is only added in track-local frames. + * Uses unsigned underflow when moving reverse (dir = -1) while on a + * pre-surface (pos = 0) to wrap to an invalid position value. + */ +CELER_FORCEINLINE_FUNCTION SurfaceTrackPosition +advance_subsurface_position_along(SurfaceTrackPosition pos, + SubsurfaceDirection dir) +{ + return pos + to_signed_offset(dir); +} + //---------------------------------------------------------------------------// /*! * Sample a valid facet normal by wrapping a roughness calculator. diff --git a/src/celeritas/optical/surface/SurfacePhysicsView.hh b/src/celeritas/optical/surface/SurfacePhysicsView.hh index 59d3b9c539..d7a6b3a20a 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsView.hh +++ b/src/celeritas/optical/surface/SurfacePhysicsView.hh @@ -18,25 +18,6 @@ namespace celeritas { namespace optical { - -namespace -{ -//---------------------------------------------------------------------------// -/*! - * Get the next track surface position in the given direction. - * - * Type-safe operation to ensure direction is only added in track-local frames. - * Uses unsigned underflow when moving reverse (dir = -1) while on a - * pre-surface (pos = 0) to wrap to an invalid position value. - */ -CELER_FORCEINLINE_FUNCTION SurfaceTrackPosition -operator+(SurfaceTrackPosition pos, SubsurfaceDirection dir) -{ - return pos + to_signed_offset(dir); -} - -} // namespace - //---------------------------------------------------------------------------// /*! * Optical surface physics data for a track. @@ -123,10 +104,6 @@ class SurfacePhysicsView SurfaceModelView surface_model(SubsurfaceDirection, SurfacePhysicsOrder) const; - // Get surface model for the given step - inline CELER_FUNCTION SurfaceModelView - surface_model(Real3 const&, SurfacePhysicsOrder) const; - // Get local facet normal inline CELER_FUNCTION Real3 const& facet_normal() const; @@ -280,7 +257,8 @@ CELER_FUNCTION bool SurfacePhysicsView::is_exiting(SubsurfaceDirection d) const CELER_EXPECT(this->is_crossing_boundary()); // Use unsigned underflow when moving reverse (-1) on the pre-surface // (position 0) to wrap to an invalid position value - return (this->subsurface_position() + d).unchecked_get() + return advance_subsurface_position_along(this->subsurface_position(), d) + .unchecked_get() >= this->num_positions(); } @@ -376,22 +354,8 @@ CELER_FUNCTION SurfaceModelView SurfacePhysicsView::surface_model( dir, SurfacePhysicsMapView{params_.model_maps[step], phys_surface}, this->subsurface_material(this->subsurface_position()), - this->subsurface_material(this->subsurface_position() + dir)}; -} - -//---------------------------------------------------------------------------// -/*! - * Get surface model view of the given step for a track moving in the given - * direction. - * - * Helper function that determines the traversal direction from the track - * direction and constructs a surface model from it. - */ -CELER_FUNCTION SurfaceModelView SurfacePhysicsView::surface_model( - Real3 const& dir, SurfacePhysicsOrder step) const -{ - CELER_EXPECT(this->is_crossing_boundary()); - return this->surface_model(this->traversal_direction(dir), step); + this->subsurface_material(advance_subsurface_position_along( + this->subsurface_position(), dir))}; } //---------------------------------------------------------------------------// @@ -424,7 +388,8 @@ SurfacePhysicsView::cross_subsurface_interface(SubsurfaceDirection d) { CELER_EXPECT(this->is_crossing_boundary()); CELER_EXPECT(!this->is_exiting(d)); - this->subsurface_position(this->subsurface_position() + d); + this->subsurface_position( + advance_subsurface_position_along(this->subsurface_position(), d)); } //---------------------------------------------------------------------------// diff --git a/src/celeritas/optical/surface/TrackSlotExecutor.hh b/src/celeritas/optical/surface/TrackSlotExecutor.hh index aa1122dad8..505464bde0 100644 --- a/src/celeritas/optical/surface/TrackSlotExecutor.hh +++ b/src/celeritas/optical/surface/TrackSlotExecutor.hh @@ -26,9 +26,11 @@ struct IsSurfaceModelEqual //! Whether the surface model should be executed for the track CELER_FUNCTION bool operator()(CoreTrackView const& track) const { - return track.surface_physics().is_crossing_boundary() - && track.surface_physics() - .surface_model(track.geometry().dir(), step) + auto s_phys = track.surface_physics(); + return s_phys.is_crossing_boundary() + && s_phys.surface_model( + s_phys.traversal_direction(track.geometry().dir()), + step) .surface_model() == model; } diff --git a/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc b/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc index 29c2363d61..8deebf9e69 100644 --- a/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc +++ b/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc @@ -30,7 +30,7 @@ GaussianRoughnessModel::GaussianRoughnessModel( : BuiltinRoughnessModel(model, "gaussian", std::move(surfaces)) { HostVal data; - auto build_sigma_alpha = ::celeritas::make_builder(&data.sigma_alpha); + auto build_sigma_alpha = CollectionBuilder{&data.sigma_alpha}; for (auto const& gaussian : inputs) { diff --git a/src/celeritas/optical/surface/model/RoughnessApplier.hh b/src/celeritas/optical/surface/model/RoughnessApplier.hh index 8ced3e683e..0ecba6224e 100644 --- a/src/celeritas/optical/surface/model/RoughnessApplier.hh +++ b/src/celeritas/optical/surface/model/RoughnessApplier.hh @@ -45,7 +45,8 @@ CELER_FUNCTION void RoughnessApplier::operator()(CoreTrackView& track) const auto const& track_dir = track.geometry().dir(); auto s_physics = track.surface_physics(); auto model_view - = s_physics.surface_model(track_dir, SurfacePhysicsOrder::roughness); + = s_physics.surface_model(s_physics.traversal_direction(track_dir), + SurfacePhysicsOrder::roughness); auto rng = track.rng(); // Ensure the local normal follows the entering surface convention diff --git a/src/celeritas/optical/surface/model/SmearRoughnessModel.cc b/src/celeritas/optical/surface/model/SmearRoughnessModel.cc index edef055126..57106219fd 100644 --- a/src/celeritas/optical/surface/model/SmearRoughnessModel.cc +++ b/src/celeritas/optical/surface/model/SmearRoughnessModel.cc @@ -29,7 +29,7 @@ SmearRoughnessModel::SmearRoughnessModel(SurfaceModelId model, : BuiltinRoughnessModel(model, "smear", std::move(surfaces)) { HostVal data; - auto build_roughness = ::celeritas::make_builder(&data.roughness); + auto build_roughness = CollectionBuilder{&data.roughness}; for (auto const& smear : inputs) { From b9da2db8de579f8d49282f6500cf767cb1e66ccb Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Thu, 18 Sep 2025 10:47:16 -0500 Subject: [PATCH 20/22] Refactored builtin surface model input --- .../detail/BuiltinSurfaceModelBuilder.hh | 79 ++----------------- .../surface/model/BuiltinSurfaceModel.hh | 79 +++++++------------ .../surface/model/GaussianRoughnessModel.cc | 8 +- .../surface/model/GaussianRoughnessModel.hh | 3 +- .../surface/model/PolishedRoughnessModel.cc | 6 +- .../surface/model/PolishedRoughnessModel.hh | 3 +- .../surface/model/SmearRoughnessModel.cc | 9 +-- .../surface/model/SmearRoughnessModel.hh | 3 +- 8 files changed, 48 insertions(+), 142 deletions(-) diff --git a/src/celeritas/optical/surface/detail/BuiltinSurfaceModelBuilder.hh b/src/celeritas/optical/surface/detail/BuiltinSurfaceModelBuilder.hh index 211d700ada..c18f035f05 100644 --- a/src/celeritas/optical/surface/detail/BuiltinSurfaceModelBuilder.hh +++ b/src/celeritas/optical/surface/detail/BuiltinSurfaceModelBuilder.hh @@ -15,13 +15,6 @@ namespace celeritas namespace optical { //---------------------------------------------------------------------------// -template<> -struct BuiltinApplier -{ - template - using Applier = TrivialApplier; -}; - namespace detail { namespace @@ -31,14 +24,15 @@ namespace * Fake model as a placeholder for surface models yet to be implemented. */ template -class FakeModel : public BuiltinSurfaceModel +class FakeModel + : public BuiltinSurfaceModel { public: FakeModel(SurfaceModelId model_id, std::string_view label, - std::vector surfaces) - : BuiltinSurfaceModel( - model_id, label, std::move(surfaces)) + std::map const& surfaces) + : BuiltinSurfaceModel( + model_id, label, surfaces) { } @@ -46,29 +40,6 @@ class FakeModel : public BuiltinSurfaceModel void step(CoreParams const&, CoreStateDevice&) const final {} }; -//---------------------------------------------------------------------------// -/*! - * Build a fake model from input. - */ -template -std::shared_ptr> -fake_builtin_model_from_input(SurfaceModelId model_id, - std::string_view label, - std::map const& layer_map) -{ - std::vector surfaces; - for (auto const& [layer, input] : layer_map) - { - CELER_EXPECT(layer); - CELER_DISCARD(input); - surfaces.push_back(layer); - } - - CELER_ENSURE(surfaces.size() == layer_map.size()); - - return std::make_shared>(model_id, label, std::move(surfaces)); -} - } // namespace //---------------------------------------------------------------------------// @@ -105,11 +76,6 @@ class BuiltinSurfaceModelBuilder private: std::vector& models_; size_type num_surf_{0}; - - // Construct built-in surface model from input - template - std::shared_ptr builtin_model_from_input( - SurfaceModelId, std::map const&); }; //---------------------------------------------------------------------------// @@ -136,8 +102,8 @@ void BuiltinSurfaceModelBuilder::build( { if (!layer_map.empty()) { - models_.push_back(builtin_model_from_input( - SurfaceModelId(models_.size()), layer_map)); + models_.push_back( + std::make_shared(SurfaceModelId(models_.size()), layer_map)); num_surf_ += layer_map.size(); } } @@ -155,41 +121,12 @@ void BuiltinSurfaceModelBuilder::build_fake( { if (!layer_map.empty()) { - models_.push_back(fake_builtin_model_from_input( + models_.push_back(std::make_shared>( SurfaceModelId(models_.size()), label, layer_map)); num_surf_ += layer_map.size(); } } -//---------------------------------------------------------------------------// -/*! - * Construct built-in model of type \c M from \c inp::SurfacePhysics surface - * layer map. - * - * The model \c M should have a type alias \c M::InputT which corresponds to - * the input type associated with each surface. - */ -template -std::shared_ptr BuiltinSurfaceModelBuilder::builtin_model_from_input( - SurfaceModelId model_id, - std::map const& layer_map) -{ - std::vector surfaces; - std::vector inputs; - - for (auto const& [surface, input] : layer_map) - { - CELER_ENSURE(surface); - surfaces.push_back(surface); - inputs.push_back(input); - } - - CELER_ENSURE(surfaces.size() == layer_map.size()); - CELER_ENSURE(inputs.size() == layer_map.size()); - - return std::make_shared(model_id, std::move(surfaces), inputs); -} - //---------------------------------------------------------------------------// } // namespace detail } // namespace optical diff --git a/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh b/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh index f727c23774..dbdcf0a7e6 100644 --- a/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh +++ b/src/celeritas/optical/surface/model/BuiltinSurfaceModel.hh @@ -32,53 +32,18 @@ struct TrivialApplier } }; -//---------------------------------------------------------------------------// -/*! - * Template trait used to select applier wrapper for built-in executors. - */ -template -struct BuiltinApplier; - -template<> -struct BuiltinApplier -{ - template - using Applier = RoughnessApplier; -}; - -template<> -struct BuiltinApplier -{ - template - using Applier = TrivialApplier; -}; - -template<> -struct BuiltinApplier -{ - template - using Applier = TrivialApplier; -}; - //---------------------------------------------------------------------------// /*! * Templated base class for built-in optical surface physics models. * * Built-in surface physics models share a common format for their input data * as well as the parameters to pass to their kernel launchers. The \c - * BuiltinApplier wrappers executor calls to factor out common behavior between + * Applier wrappers executor calls to factor out common behavior between * surface physics steps. */ -template +template class Applier> class BuiltinSurfaceModel : public SurfaceModel { - public: - //!@{ - //! \name Type aliases - template - using Applier = typename BuiltinApplier::template Applier; - //!@} - public: //! Get surfaces handled by this model. std::vector const& get_surfaces() const final @@ -88,13 +53,14 @@ class BuiltinSurfaceModel : public SurfaceModel protected: // Construct from ID, label, and surfaces + template BuiltinSurfaceModel(SurfaceModelId model_id, std::string_view label, - std::vector surfaces); + std::map const& layer_map); // Construct executor with applier wrapper template - auto make_executor(CoreParams const&, CoreState&, E&&) const; + inline auto make_executor(CoreParams const&, CoreState&, E&&) const; private: std::vector surfaces_; @@ -105,23 +71,34 @@ class BuiltinSurfaceModel : public SurfaceModel /*! * Construct from ID, label, and surfaces. */ -template -BuiltinSurfaceModel::BuiltinSurfaceModel(SurfaceModelId model_id, - std::string_view label, - std::vector surfaces) - : SurfaceModel(model_id, label), surfaces_(std::move(surfaces)) +template class Applier> +template +BuiltinSurfaceModel::BuiltinSurfaceModel( + SurfaceModelId model_id, + std::string_view label, + std::map const& layer_map) + : SurfaceModel(model_id, label) { + surfaces_.reserve(layer_map.size()); + + for (auto const& [surface, input] : layer_map) + { + CELER_ENSURE(surface); + surfaces_.push_back(surface); + } + + CELER_ENSURE(layer_map.size() == surfaces_.size()); } //---------------------------------------------------------------------------// /*! * Construct a surface physics executor with built-in applier wrapper. */ -template +template class Applier> template -auto BuiltinSurfaceModel::make_executor(CoreParams const& params, - CoreState& state, - E&& exec) const +auto BuiltinSurfaceModel::make_executor(CoreParams const& params, + CoreState& state, + E&& exec) const { return make_surface_physics_executor(params.ptr(), state.ptr(), @@ -135,11 +112,11 @@ auto BuiltinSurfaceModel::make_executor(CoreParams const& params, //---------------------------------------------------------------------------// using BuiltinRoughnessModel - = BuiltinSurfaceModel; + = BuiltinSurfaceModel; using BuiltinReflectivityModel - = BuiltinSurfaceModel; + = BuiltinSurfaceModel; using BuiltinInteractionModel - = BuiltinSurfaceModel; + = BuiltinSurfaceModel; //---------------------------------------------------------------------------// } // namespace optical diff --git a/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc b/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc index 8deebf9e69..fbc0eb492f 100644 --- a/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc +++ b/src/celeritas/optical/surface/model/GaussianRoughnessModel.cc @@ -24,15 +24,13 @@ namespace optical * Construct model from surfaces and inputs. */ GaussianRoughnessModel::GaussianRoughnessModel( - SurfaceModelId model, - std::vector surfaces, - std::vector const& inputs) - : BuiltinRoughnessModel(model, "gaussian", std::move(surfaces)) + SurfaceModelId model, std::map const& inputs) + : BuiltinRoughnessModel(model, "gaussian", inputs) { HostVal data; auto build_sigma_alpha = CollectionBuilder{&data.sigma_alpha}; - for (auto const& gaussian : inputs) + for (auto const& [surface, gaussian] : inputs) { CELER_ENSURE(gaussian); build_sigma_alpha.push_back(gaussian.sigma_alpha); diff --git a/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh b/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh index a28d7cd439..e0b5c95b67 100644 --- a/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh +++ b/src/celeritas/optical/surface/model/GaussianRoughnessModel.hh @@ -38,8 +38,7 @@ class GaussianRoughnessModel : public BuiltinRoughnessModel public: // Construct model from surfaces and inputs GaussianRoughnessModel(SurfaceModelId model, - std::vector surfaces, - std::vector const& inputs); + std::map const& inputs); // Launch kernel on host void step(CoreParams const& params, CoreStateHost& state) const final; diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc index 7e04ec7bba..3edf05dc3b 100644 --- a/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc +++ b/src/celeritas/optical/surface/model/PolishedRoughnessModel.cc @@ -23,10 +23,8 @@ namespace optical * Construct model from surfaces and inputs. */ PolishedRoughnessModel::PolishedRoughnessModel( - SurfaceModelId model, - std::vector surfaces, - std::vector const&) - : BuiltinRoughnessModel(model, "polished", std::move(surfaces)) + SurfaceModelId model, std::map const& inputs) + : BuiltinRoughnessModel(model, "polished", inputs) { } diff --git a/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh b/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh index d58d91fe11..384684258b 100644 --- a/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh +++ b/src/celeritas/optical/surface/model/PolishedRoughnessModel.hh @@ -35,8 +35,7 @@ class PolishedRoughnessModel : public BuiltinRoughnessModel public: // Construct model from surfaces and inputs PolishedRoughnessModel(SurfaceModelId model, - std::vector surfaces, - std::vector const&); + std::map const& inputs); // Launch kernel on host void step(CoreParams const& params, CoreStateHost& state) const final; diff --git a/src/celeritas/optical/surface/model/SmearRoughnessModel.cc b/src/celeritas/optical/surface/model/SmearRoughnessModel.cc index 57106219fd..5b420ef100 100644 --- a/src/celeritas/optical/surface/model/SmearRoughnessModel.cc +++ b/src/celeritas/optical/surface/model/SmearRoughnessModel.cc @@ -23,15 +23,14 @@ namespace optical /*! * Construct model from surfaces and inputs. */ -SmearRoughnessModel::SmearRoughnessModel(SurfaceModelId model, - std::vector surfaces, - std::vector const& inputs) - : BuiltinRoughnessModel(model, "smear", std::move(surfaces)) +SmearRoughnessModel::SmearRoughnessModel( + SurfaceModelId model, std::map const& inputs) + : BuiltinRoughnessModel(model, "smear", inputs) { HostVal data; auto build_roughness = CollectionBuilder{&data.roughness}; - for (auto const& smear : inputs) + for (auto const& [surface, smear] : inputs) { CELER_ENSURE(smear); build_roughness.push_back(smear.roughness); diff --git a/src/celeritas/optical/surface/model/SmearRoughnessModel.hh b/src/celeritas/optical/surface/model/SmearRoughnessModel.hh index 76125e2d3e..f877e4fc2c 100644 --- a/src/celeritas/optical/surface/model/SmearRoughnessModel.hh +++ b/src/celeritas/optical/surface/model/SmearRoughnessModel.hh @@ -38,8 +38,7 @@ class SmearRoughnessModel : public BuiltinRoughnessModel public: // Construct model from surfaces and inputs SmearRoughnessModel(SurfaceModelId model, - std::vector surfaces, - std::vector const& inputs); + std::map const& inputs); // Launch kernel on host void step(CoreParams const& params, CoreStateHost& state) const final; From 735416a9253f0062ce598ed96261511220398f2c Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Thu, 18 Sep 2025 11:26:41 -0500 Subject: [PATCH 21/22] Cache track subsurface traversal direction --- .../optical/surface/SurfaceModelView.hh | 30 +++------- .../optical/surface/SurfacePhysicsData.hh | 4 ++ .../optical/surface/SurfacePhysicsView.hh | 55 ++++++++++++++----- .../optical/surface/TrackSlotExecutor.hh | 6 +- .../detail/BuiltinSurfaceModelBuilder.hh | 5 +- .../optical/surface/model/RoughnessApplier.hh | 6 +- test/celeritas/optical/SurfacePhysics.test.cc | 14 +++-- 7 files changed, 67 insertions(+), 53 deletions(-) diff --git a/src/celeritas/optical/surface/SurfaceModelView.hh b/src/celeritas/optical/surface/SurfaceModelView.hh index 65fb6f3e0a..b6af6a124c 100644 --- a/src/celeritas/optical/surface/SurfaceModelView.hh +++ b/src/celeritas/optical/surface/SurfaceModelView.hh @@ -29,17 +29,13 @@ class SurfaceModelView //!@} public: - // Construct from a direction, map view, and materials - inline CELER_FUNCTION SurfaceModelView(SubsurfaceDirection, - SurfacePhysicsMapView, + // Construct from map view and materials + inline CELER_FUNCTION SurfaceModelView(SurfacePhysicsMapView, OptMatId pre_mat, OptMatId post_mat); - // Get subsurface track direction - inline CELER_FUNCTION SubsurfaceDirection direction() const; - // Get surface model ID - inline CELER_FUNCTION SurfaceModelId surface_model() const; + inline CELER_FUNCTION SurfaceModelId model_id() const; // Get internal surface ID for the model inline CELER_FUNCTION InternalSurfaceId internal_surface_id() const; @@ -51,7 +47,6 @@ class SurfaceModelView inline CELER_FUNCTION OptMatId post_material() const; private: - SubsurfaceDirection dir_; SurfacePhysicsMapView physics_map_; OptMatId pre_material_; OptMatId post_material_; @@ -61,34 +56,23 @@ class SurfaceModelView // INLINE DEFINITIONS //---------------------------------------------------------------------------// /*! - * Construct from track direction, physics map view, and materials. + * Construct from physics map view and materials. */ CELER_FUNCTION -SurfaceModelView::SurfaceModelView(SubsurfaceDirection dir, - SurfacePhysicsMapView physics_map, +SurfaceModelView::SurfaceModelView(SurfacePhysicsMapView physics_map, OptMatId pre_material, OptMatId post_material) - : dir_(dir) - , physics_map_(physics_map) + : physics_map_(physics_map) , pre_material_(pre_material) , post_material_(post_material) { } -//---------------------------------------------------------------------------// -/*! - * Get the subsurface track direction pointing to this surface. - */ -CELER_FUNCTION SubsurfaceDirection SurfaceModelView::direction() const -{ - return dir_; -} - //---------------------------------------------------------------------------// /*! * Get the surface model for this physics surface. */ -CELER_FUNCTION SurfaceModelId SurfaceModelView::surface_model() const +CELER_FUNCTION SurfaceModelId SurfaceModelView::model_id() const { return physics_map_.surface_model_id(); } diff --git a/src/celeritas/optical/surface/SurfacePhysicsData.hh b/src/celeritas/optical/surface/SurfacePhysicsData.hh index 19ab70aa89..8535e4eedf 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsData.hh +++ b/src/celeritas/optical/surface/SurfacePhysicsData.hh @@ -148,6 +148,7 @@ struct SurfacePhysicsStateData StateItems post_volume_material; StateItems surface_position; + StateItems track_direction; StateItems facet_normal; //! Whether data is assigned @@ -155,6 +156,7 @@ struct SurfacePhysicsStateData { return !surface.empty() && surface.size() == surface_orientation.size() && surface.size() == surface_position.size() + && surface.size() == track_direction.size() && surface.size() == pre_volume_material.size() && surface.size() == post_volume_material.size() && surface.size() == global_normal.size() @@ -174,6 +176,7 @@ struct SurfacePhysicsStateData surface_orientation = other.surface_orientation; global_normal = other.global_normal; surface_position = other.surface_position; + track_direction = other.track_direction; pre_volume_material = other.pre_volume_material; post_volume_material = other.post_volume_material; facet_normal = other.facet_normal; @@ -196,6 +199,7 @@ resize(SurfacePhysicsStateData* state, size_type size) resize(&state->surface_orientation, size); resize(&state->global_normal, size); resize(&state->surface_position, size); + resize(&state->track_direction, size); resize(&state->pre_volume_material, size); resize(&state->post_volume_material, size); resize(&state->facet_normal, size); diff --git a/src/celeritas/optical/surface/SurfacePhysicsView.hh b/src/celeritas/optical/surface/SurfacePhysicsView.hh index d7a6b3a20a..5b233bd420 100644 --- a/src/celeritas/optical/surface/SurfacePhysicsView.hh +++ b/src/celeritas/optical/surface/SurfacePhysicsView.hh @@ -95,14 +95,18 @@ class SurfacePhysicsView // Number of valid positions of the track in the surface crossing inline CELER_FUNCTION SurfaceTrackPosition::size_type num_positions() const; - // Calculate traversal direction from track momentum - inline CELER_FUNCTION SubsurfaceDirection - traversal_direction(Real3 const&) const; + // Get current track traversal direction + inline CELER_FUNCTION SubsurfaceDirection traversal_direction() const; + + // Set track traversal direction + inline CELER_FUNCTION void traversal_direction(SubsurfaceDirection); + + // Calculate and update traversal direction from track momentum + inline CELER_FUNCTION void traversal_direction(Real3 const&); // Get surface model for the given step inline CELER_FUNCTION - SurfaceModelView surface_model(SubsurfaceDirection, - SurfacePhysicsOrder) const; + SurfaceModelView surface_model(SurfacePhysicsOrder) const; // Get local facet normal inline CELER_FUNCTION Real3 const& facet_normal() const; @@ -180,6 +184,7 @@ SurfacePhysicsView::operator=(Initializer const& init) states_.global_normal[track_id_] = init.global_normal; states_.facet_normal[track_id_] = init.global_normal; states_.surface_position[track_id_] = SurfaceTrackPosition{0}; + states_.track_direction[track_id_] = SubsurfaceDirection::forward; states_.pre_volume_material[track_id_] = init.pre_volume_material; states_.post_volume_material[track_id_] = init.post_volume_material; return *this; @@ -325,24 +330,49 @@ SurfacePhysicsView::num_positions() const //---------------------------------------------------------------------------// /*! - * Calculate traversal direction from track momentum. + * Get current track traversal direction. + * + * This quantity is cached for a single loop of surface boundary crossing to + * avoid repeated queries of the geometry. The traversal direction should be + * updated when the geometry direction is updated after an interaction. + */ +CELER_FUNCTION SubsurfaceDirection SurfacePhysicsView::traversal_direction() const +{ + CELER_EXPECT(this->is_crossing_boundary()); + return states_.track_direction[track_id_]; +} + +//---------------------------------------------------------------------------// +/*! + * Set current track traversal direction. + */ +CELER_FUNCTION void +SurfacePhysicsView::traversal_direction(SubsurfaceDirection dir) +{ + CELER_EXPECT(this->is_crossing_boundary()); + states_.track_direction[track_id_] = dir; +} + +//---------------------------------------------------------------------------// +/*! + * Calculate and update traversal direction from track momentum. */ -CELER_FUNCTION SubsurfaceDirection -SurfacePhysicsView::traversal_direction(Real3 const& dir) const +CELER_FUNCTION void SurfacePhysicsView::traversal_direction(Real3 const& dir) { CELER_EXPECT(this->is_crossing_boundary()); CELER_EXPECT(is_soft_unit_vector(dir)); - return static_cast( - is_entering_surface(dir, this->global_normal())); + this->traversal_direction(static_cast( + is_entering_surface(dir, this->global_normal()))); } //---------------------------------------------------------------------------// /*! * Get surface model view of the given step in the given direction. */ -CELER_FUNCTION SurfaceModelView SurfacePhysicsView::surface_model( - SubsurfaceDirection dir, SurfacePhysicsOrder step) const +CELER_FUNCTION SurfaceModelView +SurfacePhysicsView::surface_model(SurfacePhysicsOrder step) const { + auto dir = this->traversal_direction(); CELER_EXPECT(this->is_crossing_boundary()); CELER_EXPECT(!this->is_exiting(dir)); CELER_EXPECT(step != SurfacePhysicsOrder::size_); @@ -351,7 +381,6 @@ CELER_FUNCTION SurfaceModelView SurfacePhysicsView::surface_model( CELER_ASSERT(phys_surface); return SurfaceModelView{ - dir, SurfacePhysicsMapView{params_.model_maps[step], phys_surface}, this->subsurface_material(this->subsurface_position()), this->subsurface_material(advance_subsurface_position_along( diff --git a/src/celeritas/optical/surface/TrackSlotExecutor.hh b/src/celeritas/optical/surface/TrackSlotExecutor.hh index 505464bde0..477cbc89e1 100644 --- a/src/celeritas/optical/surface/TrackSlotExecutor.hh +++ b/src/celeritas/optical/surface/TrackSlotExecutor.hh @@ -28,11 +28,7 @@ struct IsSurfaceModelEqual { auto s_phys = track.surface_physics(); return s_phys.is_crossing_boundary() - && s_phys.surface_model( - s_phys.traversal_direction(track.geometry().dir()), - step) - .surface_model() - == model; + && s_phys.surface_model(step).model_id() == model; } }; diff --git a/src/celeritas/optical/surface/detail/BuiltinSurfaceModelBuilder.hh b/src/celeritas/optical/surface/detail/BuiltinSurfaceModelBuilder.hh index c18f035f05..dce8106339 100644 --- a/src/celeritas/optical/surface/detail/BuiltinSurfaceModelBuilder.hh +++ b/src/celeritas/optical/surface/detail/BuiltinSurfaceModelBuilder.hh @@ -64,11 +64,12 @@ class BuiltinSurfaceModelBuilder // Construct a fake surface model template - void build_fake(std::string_view label, std::map const&); + inline void + build_fake(std::string_view label, std::map const&); // Construct a built-in surface model template - void build(std::map const&); + inline void build(std::map const&); // Number of physics surfaces that have been constructed size_type num_surfaces() const { return num_surf_; } diff --git a/src/celeritas/optical/surface/model/RoughnessApplier.hh b/src/celeritas/optical/surface/model/RoughnessApplier.hh index 0ecba6224e..cc36501644 100644 --- a/src/celeritas/optical/surface/model/RoughnessApplier.hh +++ b/src/celeritas/optical/surface/model/RoughnessApplier.hh @@ -44,14 +44,12 @@ CELER_FUNCTION void RoughnessApplier::operator()(CoreTrackView& track) const { auto const& track_dir = track.geometry().dir(); auto s_physics = track.surface_physics(); - auto model_view - = s_physics.surface_model(s_physics.traversal_direction(track_dir), - SurfacePhysicsOrder::roughness); + auto model_view = s_physics.surface_model(SurfacePhysicsOrder::roughness); auto rng = track.rng(); // Ensure the local normal follows the entering surface convention auto normal = s_physics.global_normal(); - if (model_view.direction() == SubsurfaceDirection::reverse) + if (s_physics.traversal_direction() == SubsurfaceDirection::reverse) { normal = -normal; } diff --git a/test/celeritas/optical/SurfacePhysics.test.cc b/test/celeritas/optical/SurfacePhysics.test.cc index 5d07e02c78..67badc59a7 100644 --- a/test/celeritas/optical/SurfacePhysics.test.cc +++ b/test/celeritas/optical/SurfacePhysics.test.cc @@ -91,13 +91,13 @@ TraceResult trace_directions(SurfacePhysicsView& s_physics, for (auto direction : directions) { + s_physics.traversal_direction(direction); + for (auto step : range(SurfacePhysicsOrder::size_)) { - auto surface_model = s_physics.surface_model(direction, step); - - EXPECT_EQ(direction, surface_model.direction()); + auto surface_model = s_physics.surface_model(step); - result.models[step].push_back(surface_model.surface_model()); + result.models[step].push_back(surface_model.model_id()); result.per_model_ids[step].push_back( surface_model.internal_surface_id()); result.pre_material[step].push_back(surface_model.pre_material()); @@ -739,7 +739,8 @@ TEST_F(SurfacePhysicsTest, traversal_direction) std::vector directions; for (auto const& dir : geo_directions) { - directions.push_back(s_physics.traversal_direction(dir)); + s_physics.traversal_direction(dir); + directions.push_back(s_physics.traversal_direction()); } std::vector expected_directions{ @@ -770,7 +771,8 @@ TEST_F(SurfacePhysicsTest, traversal_direction) std::vector directions; for (auto const& dir : geo_directions) { - directions.push_back(s_physics.traversal_direction(dir)); + s_physics.traversal_direction(dir); + directions.push_back(s_physics.traversal_direction()); } std::vector expected_directions{ From c6aa9e196898fbb88b12c2bc28df32a76327bcd5 Mon Sep 17 00:00:00 2001 From: Hayden Hollenbeck Date: Thu, 18 Sep 2025 11:59:00 -0500 Subject: [PATCH 22/22] Re-enabled celer-sim tests involving surface normals --- app/celer-sim/CMakeLists.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/celer-sim/CMakeLists.txt b/app/celer-sim/CMakeLists.txt index 77b74a4ac9..ea3b652213 100644 --- a/app/celer-sim/CMakeLists.txt +++ b/app/celer-sim/CMakeLists.txt @@ -133,9 +133,4 @@ celer_sim_test(lar lar-sphere.gdml gamma-4evt-15prim.hepmc3 lar-mctruth.root ) -if(NOT CELERITAS_CORE_GEO STREQUAL "ORANGE") - set_tests_properties("app/celer-sim:lar:cpu" PROPERTIES DISABLED True) - set_tests_properties("app/celer-sim:lar:gpu" PROPERTIES DISABLED True) -endif() - #-----------------------------------------------------------------------------#