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