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/containers.hpp"
0014 #include "detray/definitions/detail/qualifiers.hpp"
0015 #include "detray/definitions/indexing.hpp"
0016 #include "detray/definitions/math.hpp"
0017 #include "detray/definitions/units.hpp"
0018 #include "detray/geometry/coordinates/cartesian3D.hpp"
0019 #include "detray/geometry/coordinates/cylindrical2D.hpp"
0020 #include "detray/geometry/detail/shape_utils.hpp"
0021
0022
0023 #include <limits>
0024 #include <ostream>
0025 #include <string_view>
0026
0027 namespace detray {
0028
0029
0030
0031
0032 class cylinder2D {
0033 public:
0034
0035 static constexpr std::string_view name = "cylinder2D";
0036
0037 enum boundaries : unsigned int {
0038 e_r = 0u,
0039 e_lower_z = 1u,
0040 e_upper_z = 2u,
0041 e_size = 3u,
0042 };
0043
0044
0045 template <concepts::scalar scalar_t>
0046 using bounds_type = darray<scalar_t, boundaries::e_size>;
0047
0048
0049 template <concepts::algebra algebra_t>
0050 using local_frame_type = cylindrical2D<algebra_t>;
0051
0052
0053 template <typename bool_t>
0054 using result_type = detail::boundary_check_result<bool_t>;
0055
0056
0057 static constexpr std::size_t dim{2u};
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068 template <concepts::scalar scalar_t, concepts::point point_t>
0069 DETRAY_HOST_DEVICE inline scalar_t min_dist_to_boundary(
0070 const bounds_type<scalar_t> &bounds, const point_t &loc_p) const {
0071 return math::min(math::fabs(loc_p[1] - bounds[e_lower_z]),
0072 math::fabs(bounds[e_upper_z] - loc_p[1]));
0073 }
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083 template <concepts::algebra algebra_t>
0084 DETRAY_HOST_DEVICE constexpr result_type<dbool<algebra_t>> check_boundaries(
0085 const bounds_type<dscalar<algebra_t>> &bounds,
0086 const dtransform3D<algebra_t> &trf, const dpoint3D<algebra_t> &glob_p,
0087 const dscalar<algebra_t> tol =
0088 std::numeric_limits<dscalar<algebra_t>>::epsilon(),
0089 const dscalar<algebra_t> edge_tol = 0.f) const {
0090
0091 const auto loc_p = cartesian3D<algebra_t>::global_to_local(trf, glob_p, {});
0092
0093
0094 return check_boundaries(
0095 bounds,
0096 dpoint2D<algebra_t>{static_cast<dscalar<algebra_t>>(0.f), loc_p[2]},
0097 tol, edge_tol);
0098 }
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113 template <concepts::scalar scalar_t, concepts::point point_t>
0114 DETRAY_HOST_DEVICE constexpr auto check_boundaries(
0115 const bounds_type<scalar_t> &bounds, const point_t &loc_p,
0116 const scalar_t tol = std::numeric_limits<scalar_t>::epsilon(),
0117 const scalar_t edge_tol = 0.f) const {
0118 auto inside_mask{((bounds[e_lower_z] - tol) <= loc_p[1] &&
0119 loc_p[1] <= (bounds[e_upper_z] + tol))};
0120
0121 decltype(inside_mask) inside_edge{false};
0122 if (detail::any_of(edge_tol > 0.f)) {
0123 const scalar_t full_tol{tol + edge_tol};
0124 inside_edge = ((bounds[e_lower_z] - full_tol) <= loc_p[1] &&
0125 loc_p[1] <= (bounds[e_upper_z] + full_tol));
0126 }
0127
0128 return result_type<decltype(inside_mask)>{inside_mask, inside_edge};
0129 }
0130
0131
0132
0133
0134
0135
0136
0137 template <concepts::scalar scalar_t>
0138 DETRAY_HOST_DEVICE constexpr scalar_t measure(
0139 const bounds_type<scalar_t> &bounds) const {
0140 return area(bounds);
0141 }
0142
0143
0144
0145
0146
0147
0148 template <concepts::scalar scalar_t>
0149 DETRAY_HOST_DEVICE constexpr scalar_t area(
0150 const bounds_type<scalar_t> &bounds) const {
0151 return 2.f * constant<scalar_t>::pi * bounds[e_r] *
0152 (bounds[e_upper_z] - bounds[e_lower_z]);
0153 }
0154
0155
0156
0157
0158
0159
0160
0161 template <concepts::scalar scalar_t>
0162 DETRAY_HOST_DEVICE constexpr bounds_type<scalar_t> merge(
0163 const bounds_type<scalar_t> &bounds,
0164 const bounds_type<scalar_t> &o_bounds) const {
0165 bounds_type<scalar_t> new_bounds{};
0166
0167 new_bounds[e_r] = math::max(bounds[e_r], o_bounds[e_r]);
0168 new_bounds[e_lower_z] = math::min(bounds[e_lower_z], o_bounds[e_lower_z]);
0169 new_bounds[e_upper_z] = math::max(bounds[e_upper_z], o_bounds[e_upper_z]);
0170
0171 return new_bounds;
0172 }
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183 template <concepts::algebra algebra_t>
0184 DETRAY_HOST_DEVICE inline darray<dscalar<algebra_t>, 6> local_min_bounds(
0185 const bounds_type<dscalar<algebra_t>> &bounds,
0186 const dscalar<algebra_t> env =
0187 std::numeric_limits<dscalar<algebra_t>>::epsilon()) const {
0188 assert(env > 0.f);
0189
0190 const dscalar<algebra_t> xy_bound{bounds[e_r] + env};
0191 return {-xy_bound, -xy_bound, bounds[e_lower_z] - env,
0192 xy_bound, xy_bound, bounds[e_upper_z] + env};
0193 }
0194
0195
0196 template <concepts::algebra algebra_t>
0197 DETRAY_HOST_DEVICE dpoint3D<algebra_t> centroid(
0198 const bounds_type<dscalar<algebra_t>> &bounds) const {
0199 return {static_cast<dscalar<algebra_t>>(0.f),
0200 static_cast<dscalar<algebra_t>>(0.f),
0201 0.5f * (bounds[e_lower_z] + bounds[e_upper_z])};
0202 }
0203
0204
0205
0206
0207
0208
0209
0210 template <concepts::algebra algebra_t>
0211 DETRAY_HOST dvector<dpoint3D<algebra_t>> vertices(
0212 const bounds_type<dscalar<algebra_t>> & ,
0213 dindex ) const {
0214 throw std::runtime_error(
0215 "Vertex generation for cylinders is not implemented");
0216 return {};
0217 }
0218
0219
0220
0221
0222
0223
0224
0225 template <concepts::scalar scalar_t>
0226 DETRAY_HOST constexpr bool check_consistency(
0227 const bounds_type<scalar_t> &bounds, std::ostream &os) const {
0228 constexpr auto tol{10.f * std::numeric_limits<scalar_t>::epsilon()};
0229
0230 if (bounds[e_r] < tol) {
0231 os << "DETRAY ERROR (HOST): Radius must be in the range (0, "
0232 "numeric_max)"
0233 << std::endl;
0234 return false;
0235 }
0236 if (bounds[e_lower_z] >= bounds[e_upper_z] ||
0237 math::fabs(bounds[e_lower_z] - bounds[e_upper_z]) < tol) {
0238 os << "DETRAY ERROR (HOST): Neg. half length must be smaller than "
0239 "pos. half "
0240 "length.";
0241 return false;
0242 }
0243
0244 return true;
0245 }
0246 };
0247
0248 }