File indexing completed on 2026-11-07 10:11:39
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/random/distribution/BernoulliDistribution.hh"
0010 #include "corecel/random/distribution/Selector.hh"
0011 #include "celeritas/Quantities.hh"
0012 #include "celeritas/grid/NonuniformGridCalculator.hh"
0013 #include "celeritas/optical/CoreTrackView.hh"
0014
0015 #include "GridReflectivityData.hh"
0016
0017 namespace celeritas
0018 {
0019 namespace optical
0020 {
0021
0022
0023
0024
0025
0026 class GridReflectivityCalculator
0027 {
0028 public:
0029
0030
0031 using DataRef = NativeCRef<GridReflectivityData>;
0032 using Energy = units::MevEnergy;
0033
0034
0035 public:
0036
0037 explicit inline CELER_FUNCTION GridReflectivityCalculator(
0038 DataRef const&, SubModelId, Energy);
0039
0040
0041 inline CELER_FUNCTION real_type operator()(ReflectivityAction) const;
0042
0043 private:
0044 DataRef const& data_;
0045 SubModelId surface_;
0046 Energy energy_;
0047 };
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 struct GridReflectivityExecutor
0059 {
0060
0061
0062 using Energy = units::MevEnergy;
0063
0064
0065 NativeCRef<GridReflectivityData> data;
0066
0067
0068 inline CELER_FUNCTION ReflectivityAction operator()(
0069 CoreTrackView const& track) const;
0070 };
0071
0072
0073
0074
0075
0076
0077
0078 CELER_FUNCTION GridReflectivityCalculator::GridReflectivityCalculator(
0079 DataRef const& data, SubModelId surface, Energy energy)
0080 : data_(data), surface_(surface), energy_(energy)
0081 {
0082 }
0083
0084
0085
0086
0087
0088 CELER_FUNCTION real_type GridReflectivityCalculator::operator()(
0089 ReflectivityAction action) const
0090 {
0091 CELER_EXPECT(surface_ < data_.reflectivity[action].size());
0092 auto grid = data_.reflectivity[action][surface_];
0093
0094 CELER_ASSERT(grid);
0095
0096 NonuniformGridCalculator calc_grid{grid, data_.reals};
0097 real_type result = calc_grid(value_as<Energy>(energy_));
0098
0099
0100 CELER_ENSURE(0 <= result && result <= 1);
0101
0102 return result;
0103 }
0104
0105
0106
0107
0108
0109 CELER_FUNCTION ReflectivityAction GridReflectivityExecutor::operator()(
0110 CoreTrackView const& track) const
0111 {
0112 using namespace celeritas::literals;
0113
0114 auto s_phys = track.surface_physics();
0115 auto sub_model_id
0116 = s_phys.interface(SurfacePhysicsOrder::reflectivity).internal_surface_id();
0117
0118 auto rng = track.rng();
0119
0120
0121 auto action = celeritas::make_unnormalized_selector(
0122 GridReflectivityCalculator{
0123 data, sub_model_id, track.particle().energy()},
0124 ReflectivityAction::size_,
0125 1.0_r)(rng);
0126
0127 if (action == ReflectivityAction::absorb)
0128 {
0129 if (auto e_grid_id = data.efficiency_ids[sub_model_id].get())
0130 {
0131
0132 auto const& e_grid = data.efficiency[e_grid_id];
0133
0134 CELER_ASSERT(e_grid);
0135
0136 real_type efficiency = NonuniformGridCalculator{e_grid, data.reals}(
0137 value_as<Energy>(track.particle().energy()));
0138
0139 if (BernoulliDistribution{efficiency}(rng))
0140 {
0141
0142 action = ReflectivityAction::transmit;
0143 }
0144 }
0145 }
0146
0147 return action;
0148 }
0149
0150
0151 }
0152 }