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