Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-07 10:11:39

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file celeritas/optical/surface/model/SurfaceInteractionApplier.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "celeritas/optical/CoreTrackView.hh"
0010 
0011 #include "SurfaceInteraction.hh"
0012 
0013 namespace celeritas
0014 {
0015 namespace optical
0016 {
0017 //---------------------------------------------------------------------------//
0018 /*!
0019  * Wrap a surface interaction executor and apply it to a track.
0020  *
0021  * The functor \c F must take a \c CoreTrackView and return a \c
0022  * SurfaceInteraction.
0023  */
0024 template<class F>
0025 struct SurfaceInteractionApplier
0026 {
0027     F sample_interaction;
0028 
0029     inline CELER_FUNCTION void operator()(CoreTrackView const&) const;
0030 };
0031 
0032 //---------------------------------------------------------------------------//
0033 // DEDUCTION GUIDES
0034 //---------------------------------------------------------------------------//
0035 template<class F>
0036 CELER_CTAD_FUNCTION SurfaceInteractionApplier(F&&)
0037     -> SurfaceInteractionApplier<F>;
0038 
0039 //---------------------------------------------------------------------------//
0040 // INLINE DEFINITIONS
0041 //---------------------------------------------------------------------------//
0042 /*!
0043  * Apply sampled surface interaction to the track.
0044  */
0045 template<class F>
0046 CELER_FUNCTION void SurfaceInteractionApplier<F>::operator()(
0047     CoreTrackView const& track) const
0048 {
0049     // Sample interaction
0050     SurfaceInteraction result = this->sample_interaction(track);
0051 
0052     CELER_ASSERT(result.is_valid());
0053 
0054     if (result.action == SurfaceInteraction::Action::absorbed)
0055     {
0056         // Mark particle as killed
0057         track.sim().status(TrackStatus::killed);
0058     }
0059     else
0060     {
0061         // Cross boundary if refracted or transmitted
0062         auto surface_physics = track.surface_physics();
0063         auto traverse = surface_physics.traversal();
0064         if (result.action != SurfaceInteraction::Action::reflected)
0065         {
0066             traverse.cross_interface(traverse.dir());
0067         }
0068 
0069         if (result.action != SurfaceInteraction::Action::transmitted)
0070         {
0071             // Update direction and polarization
0072             track.geometry().set_dir(result.direction);
0073             track.particle().polarization(result.polarization);
0074             surface_physics.update_traversal_direction(result.direction);
0075         }
0076 
0077         // Ensure no other interactions are taken this step
0078         // TODO: switch to more general surface crossing status?
0079         surface_physics.reflectivity_action(ReflectivityAction::transmit);
0080 
0081         if (traverse.is_exiting())
0082         {
0083             // End boundary crossing if exiting
0084             track.sim().post_step_action(
0085                 surface_physics.scalars().post_boundary_action);
0086         }
0087     }
0088 }
0089 
0090 //---------------------------------------------------------------------------//
0091 }  // namespace optical
0092 }  // namespace celeritas