File indexing completed on 2026-11-07 10:11:39
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/Assert.hh"
0010 #include "corecel/Macros.hh"
0011 #include "corecel/math/ArrayOperators.hh"
0012 #include "celeritas/geo/CoreGeoTrackView.hh"
0013 #include "celeritas/optical/CoreTrackView.hh"
0014 #include "celeritas/optical/SimTrackView.hh"
0015 #include "celeritas/optical/Types.hh"
0016 #include "celeritas/optical/surface/VolumeSurfaceSelector.hh"
0017
0018 namespace celeritas
0019 {
0020 namespace optical
0021 {
0022 namespace detail
0023 {
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 struct InitBoundaryExecutor
0038 {
0039
0040 inline CELER_FUNCTION void operator()(CoreTrackView& track) const;
0041 };
0042
0043
0044
0045
0046
0047
0048
0049 CELER_FUNCTION void InitBoundaryExecutor::operator()(CoreTrackView& track) const
0050 {
0051 CELER_EXPECT([track] {
0052 auto sim = track.sim();
0053 return sim.post_step_action()
0054 == track.surface_physics().scalars().init_boundary_action
0055 && sim.status() == TrackStatus::alive;
0056 }());
0057
0058 auto geo = track.geometry();
0059 CELER_EXPECT(geo.is_on_boundary());
0060
0061
0062
0063 VolumeSurfaceSelector select_surface{track.surface(),
0064 geo.volume_instance_id()};
0065 OptMatId pre_volume_material = track.material_record().material_id();
0066
0067
0068 geo.cross_boundary();
0069 if (CELER_UNLIKELY(geo.failed()))
0070 {
0071 track.apply_errored();
0072 return;
0073 }
0074 if (CELER_UNLIKELY(geo.is_outside()))
0075 {
0076 track.sim().status(TrackStatus::killed);
0077 return;
0078 }
0079 OptMatId post_volume_material = track.material_record().material_id();
0080 auto surface_physics = track.surface_physics();
0081
0082
0083
0084 auto oriented_surface
0085 = select_surface(track.surface(), geo.volume_instance_id());
0086 if (!oriented_surface)
0087 {
0088
0089 oriented_surface.surface = surface_physics.scalars().default_surface;
0090 oriented_surface.orientation = LocalDirection::forward;
0091 }
0092
0093
0094
0095 Real3 global_normal = geo.normal();
0096 if (!is_entering_surface(geo.dir(), global_normal))
0097 {
0098 global_normal = -global_normal;
0099 }
0100
0101 surface_physics = [&] {
0102 SurfacePhysicsTrackView::Initializer init;
0103 init.surface = oriented_surface.surface;
0104 init.orientation = oriented_surface.orientation;
0105 init.global_normal = global_normal;
0106 init.pre_volume_material = pre_volume_material;
0107
0108 init.post_volume_material = post_volume_material;
0109 return init;
0110 }();
0111
0112 CELER_ASSERT(
0113 is_entering_surface(geo.dir(), surface_physics.global_normal()));
0114
0115 track.sim().post_step_action(
0116 surface_physics.scalars().surface_stepping_action);
0117 }
0118
0119
0120 }
0121 }
0122 }