File indexing completed on 2025-09-17 09:07:50
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/math/Algorithms.hh"
0010 #include "orange/OrangeData.hh"
0011
0012 #include "SurfaceTypeTraits.hh"
0013
0014 #include "detail/AllSurfaces.hh"
0015
0016 namespace celeritas
0017 {
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 class LocalSurfaceVisitor
0033 {
0034 public:
0035
0036
0037 using ParamsRef = NativeCRef<OrangeParamsData>;
0038
0039
0040 public:
0041
0042 inline CELER_FUNCTION
0043 LocalSurfaceVisitor(ParamsRef const& params,
0044 SurfacesRecord const& local_surfaces);
0045
0046
0047 inline CELER_FUNCTION
0048 LocalSurfaceVisitor(ParamsRef const& params, SimpleUnitId unit);
0049
0050
0051 template<class F>
0052 inline CELER_FUNCTION decltype(auto)
0053 operator()(F&& typed_visitor, LocalSurfaceId t);
0054
0055 private:
0056
0057
0058 template<class T>
0059 using Items = Collection<T, Ownership::const_reference, MemSpace::native>;
0060
0061
0062
0063 ParamsRef const& params_;
0064 SurfacesRecord const& surfaces_;
0065
0066
0067
0068
0069 template<class T>
0070 inline CELER_FUNCTION T make_surface(LocalSurfaceId data_offset) const;
0071
0072
0073 template<class T, class U>
0074 static inline CELER_FUNCTION T get_item(Items<T> const& items,
0075 ItemRange<T> const& range,
0076 ItemId<U> item);
0077 };
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087 CELER_FORCEINLINE_FUNCTION
0088 LocalSurfaceVisitor::LocalSurfaceVisitor(ParamsRef const& params,
0089 SurfacesRecord const& local_surfaces)
0090 : params_{params}, surfaces_{local_surfaces}
0091 {
0092 }
0093
0094
0095
0096
0097
0098 CELER_FORCEINLINE_FUNCTION
0099 LocalSurfaceVisitor::LocalSurfaceVisitor(ParamsRef const& params,
0100 SimpleUnitId unit)
0101 : LocalSurfaceVisitor{params, params.simple_units[unit].surfaces}
0102 {
0103 }
0104
0105 #if !defined(__DOXYGEN__) || __DOXYGEN__ > 0x010908
0106
0107
0108
0109
0110 template<class F>
0111 CELER_FUNCTION decltype(auto)
0112 LocalSurfaceVisitor::operator()(F&& func, LocalSurfaceId id)
0113 {
0114 CELER_EXPECT(id < surfaces_.size());
0115
0116
0117 return visit_surface_type(
0118 [this, &func, id](auto s_traits) {
0119
0120 using S = typename decltype(s_traits)::type;
0121 return func(this->make_surface<S>(id));
0122 },
0123 this->get_item(params_.surface_types, surfaces_.types, id));
0124 }
0125 #endif
0126
0127
0128
0129
0130
0131
0132
0133 template<class T>
0134 CELER_FUNCTION T LocalSurfaceVisitor::make_surface(LocalSurfaceId id) const
0135 {
0136 using Reals = decltype(params_.reals);
0137 using ItemIdT = typename Reals::ItemIdT;
0138 using ItemRangeT = typename Reals::ItemRangeT;
0139 ItemIdT offset
0140 = this->get_item(params_.real_ids, surfaces_.data_offsets, id);
0141 constexpr size_type size{T::StorageSpan::extent};
0142 CELER_ASSERT(offset + size <= params_.reals.size());
0143 auto storage_span = params_.reals[ItemRangeT{offset, offset + size}];
0144
0145
0146 return T{storage_span.template first<size>()};
0147 }
0148
0149
0150
0151
0152
0153
0154 template<class T, class U>
0155 CELER_FORCEINLINE_FUNCTION T LocalSurfaceVisitor::get_item(
0156 Items<T> const& items, ItemRange<T> const& offsets, ItemId<U> item)
0157 {
0158 CELER_EXPECT(*offsets.end() <= items.size());
0159 CELER_EXPECT(item < offsets.size());
0160 return items[offsets][item.unchecked_get()];
0161 }
0162
0163
0164 }