File indexing completed on 2026-05-27 07:23:58
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
0012 #include "detray/definitions/algebra.hpp"
0013 #include "detray/definitions/detail/qualifiers.hpp"
0014 #include "detray/definitions/indexing.hpp"
0015 #include "detray/material/concepts.hpp"
0016 #include "detray/material/detail/material_accessor.hpp"
0017 #include "detray/material/material.hpp"
0018 #include "detray/utils/concepts.hpp"
0019 #include "detray/utils/ranges.hpp"
0020
0021
0022 #include <limits>
0023 #include <ostream>
0024 #include <ranges>
0025
0026 namespace detray::detail {
0027
0028
0029 template <concepts::algebra algebra_t>
0030 struct surface_kernels {
0031 using algebra_type = algebra_t;
0032 using scalar_type = dscalar<algebra_t>;
0033 using point2_type = dpoint2D<algebra_t>;
0034 using point3_type = dpoint3D<algebra_t>;
0035 using vector3_type = dvector3D<algebra_t>;
0036 using transform3_type = dtransform3D<algebra_t>;
0037
0038
0039 struct get_shape_name {
0040 template <typename mask_group_t, typename index_t>
0041 DETRAY_HOST inline std::string operator()(const mask_group_t& ,
0042 const index_t ) const {
0043 return std::string(mask_group_t::value_type::shape::name);
0044 }
0045 };
0046
0047
0048
0049 struct is_inside {
0050 template <typename mask_group_t, typename idx_range_t>
0051 DETRAY_HOST_DEVICE constexpr bool operator()(const mask_group_t& mask_group,
0052 const idx_range_t idx_range,
0053 const point3_type& loc_p,
0054 const scalar_type tol) const {
0055 for (const auto& mask : detray::ranges::subrange(mask_group, idx_range)) {
0056 if (mask.is_inside(loc_p, tol)) {
0057 return true;
0058 }
0059 }
0060
0061 return false;
0062 }
0063 };
0064
0065
0066 struct mask_self_check {
0067 template <typename mask_group_t, typename idx_range_t>
0068 DETRAY_HOST_DEVICE constexpr auto operator()(const mask_group_t& mask_group,
0069 const idx_range_t idx_range,
0070 std::ostream& os) const {
0071 bool is_good{true};
0072 for (const auto& mask : detray::ranges::subrange(mask_group, idx_range)) {
0073 is_good = is_good && mask.self_check(os);
0074 }
0075
0076 return is_good;
0077 }
0078 };
0079
0080
0081 struct get_volume_links {
0082 template <typename mask_group_t, typename idx_range_t>
0083 DETRAY_HOST inline auto operator()(const mask_group_t& mask_group,
0084 const idx_range_t idx_range) const {
0085 using volume_link_t = typename mask_group_t::value_type::links_type;
0086
0087 dvector<volume_link_t> volume_links{};
0088
0089 for (const auto& mask : detray::ranges::subrange(mask_group, idx_range)) {
0090 volume_links.push_back(mask.volume_link());
0091 }
0092
0093 return volume_links;
0094 }
0095 };
0096
0097
0098 struct get_mask_value {
0099 template <typename mask_group_t, typename idx_range_t>
0100 DETRAY_HOST inline auto operator()(const mask_group_t& mask_group,
0101 const idx_range_t idx_range,
0102 const std::size_t i) const {
0103 dvector<scalar_type> values{};
0104
0105 for (const auto& mask : detray::ranges::subrange(mask_group, idx_range)) {
0106 values.push_back(mask[i]);
0107 }
0108
0109 return values;
0110 }
0111 };
0112
0113
0114 struct get_mask_values {
0115 template <typename mask_group_t, typename idx_range_t>
0116 DETRAY_HOST inline auto operator()(const mask_group_t& mask_group,
0117 const idx_range_t idx_range) const {
0118 dvector<dvector<scalar_type>> values{};
0119
0120 for (const auto& mask : detray::ranges::subrange(mask_group, idx_range)) {
0121 dvector<scalar_type>& sub_mask_values = values.emplace_back();
0122 std::ranges::copy(mask.values(), std::back_inserter(sub_mask_values));
0123 }
0124
0125 return values;
0126 }
0127 };
0128
0129
0130 struct get_material_params {
0131 template <typename mat_group_t, concepts::index index_t>
0132 DETRAY_HOST_DEVICE constexpr auto operator()(
0133 const mat_group_t& mat_group, const index_t idx,
0134 const point2_type& loc_p) const {
0135 using material_t = typename mat_group_t::value_type;
0136
0137 if constexpr (concepts::surface_material<material_t>) {
0138 return &(detail::material_accessor::get(mat_group, idx, loc_p)
0139 .get_material());
0140 } else {
0141 using scalar_t = typename material_t::scalar_type;
0142
0143 return static_cast<const material<scalar_t>*>(nullptr);
0144 }
0145 }
0146 };
0147
0148
0149 struct normal {
0150 template <typename mask_group_t, typename index_t>
0151 DETRAY_HOST_DEVICE constexpr point3_type operator()(
0152 const mask_group_t& , const index_t ,
0153 const transform3_type& trf3, const point3_type& local) const {
0154 using mask_t = typename mask_group_t::value_type;
0155
0156 return mask_t::get_local_frame().normal(trf3, local);
0157 }
0158
0159 template <typename mask_group_t, concepts::index index_t>
0160 DETRAY_HOST_DEVICE constexpr point3_type operator()(
0161 const mask_group_t& mask_group, const index_t index,
0162 const transform3_type& trf3, const point2_type& bound) const {
0163 using mask_t = typename mask_group_t::value_type;
0164
0165 return mask_t::get_local_frame().normal(trf3, bound, mask_group[index]);
0166 }
0167
0168 template <typename mask_group_t, concepts::interval idx_range_t>
0169 DETRAY_HOST_DEVICE constexpr point3_type operator()(
0170 const mask_group_t& mask_group, const idx_range_t idx_range,
0171 const transform3_type& trf3, const point2_type& bound) const {
0172 using mask_t = typename mask_group_t::value_type;
0173
0174
0175
0176 const mask_t& mask = mask_group[idx_range.lower()];
0177 return mask_t::get_local_frame().normal(trf3, bound, mask);
0178 }
0179 };
0180
0181
0182 struct centroid {
0183 template <typename mask_group_t, concepts::index index_t>
0184 DETRAY_HOST_DEVICE constexpr point3_type operator()(
0185 const mask_group_t& mask_group, const index_t index) const {
0186 return mask_group[index].centroid();
0187 }
0188
0189 template <typename mask_group_t, concepts::interval idx_range_t>
0190 DETRAY_HOST_DEVICE constexpr point3_type operator()(
0191 const mask_group_t& mask_group, const idx_range_t idx_range) const {
0192 using mask_t = typename mask_group_t::value_type;
0193 using index_t = typename idx_range_t::index_type;
0194
0195 if (idx_range.size() > 1u) {
0196
0197 mask_t sf_mask = mask_group[idx_range.lower()];
0198
0199 const idx_range_t other_masks{
0200 idx_range.lower() + 1u,
0201 static_cast<index_t>(idx_range.size() - 1u)};
0202
0203
0204 for (const auto& sub_mask :
0205 detray::ranges::subrange(mask_group, other_masks)) {
0206 sf_mask = sf_mask + sub_mask;
0207 }
0208
0209 return sf_mask.centroid();
0210 } else {
0211 return mask_group[idx_range.lower()].centroid();
0212 }
0213 }
0214 };
0215
0216
0217 struct global_to_local {
0218 template <typename mask_group_t, typename index_t>
0219 DETRAY_HOST_DEVICE constexpr point3_type operator()(
0220 const mask_group_t& , const index_t& ,
0221 const transform3_type& trf3, const point3_type& global,
0222 const vector3_type& dir) const {
0223 using mask_t = typename mask_group_t::value_type;
0224
0225 return mask_t::to_local_frame3D(trf3, global, dir);
0226 }
0227 };
0228
0229
0230 struct local_to_global {
0231 template <typename mask_group_t, concepts::index index_t>
0232 DETRAY_HOST_DEVICE constexpr point3_type operator()(
0233 const mask_group_t& mask_group, const index_t index,
0234 const transform3_type& trf3, const point2_type& bound,
0235 const vector3_type& dir) const {
0236 using mask_t = typename mask_group_t::value_type;
0237
0238 return mask_t::get_local_frame().local_to_global(trf3, mask_group[index],
0239 bound, dir);
0240 }
0241
0242 template <typename mask_group_t, concepts::interval idx_range_t>
0243 DETRAY_HOST_DEVICE constexpr point3_type operator()(
0244 const mask_group_t& mask_group, const idx_range_t idx_range,
0245 const transform3_type& trf3, const point2_type& bound,
0246 const vector3_type& dir) const {
0247 using mask_t = typename mask_group_t::value_type;
0248
0249
0250
0251 const mask_t& mask = mask_group[idx_range.lower()];
0252 return mask_t::get_local_frame().local_to_global(trf3, mask, bound, dir);
0253 }
0254
0255 template <typename mask_group_t, typename index_t>
0256 DETRAY_HOST_DEVICE constexpr point3_type operator()(
0257 const mask_group_t& , const index_t& ,
0258 const transform3_type& trf3, const point3_type& local,
0259 const vector3_type& ) const {
0260 using mask_t = typename mask_group_t::value_type;
0261
0262 return mask_t::to_global_frame(trf3, local);
0263 }
0264 };
0265 };
0266
0267 }