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/polar2D.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
0033 class ring2D {
0034 public:
0035
0036 static constexpr std::string_view name = "ring2D";
0037
0038 enum boundaries : unsigned int {
0039 e_inner_r = 0u,
0040 e_outer_r = 1u,
0041 e_size = 2u,
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 = polar2D<algebra_t>;
0051
0052
0053 template <typename bool_t>
0054 using result_type = 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[0] - bounds[e_inner_r]),
0072 math::fabs(bounds[e_outer_r] - loc_p[0]));
0073 }
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084 template <concepts::algebra algebra_t>
0085 DETRAY_HOST_DEVICE constexpr result_type<dbool<algebra_t>> check_boundaries(
0086 const bounds_type<dscalar<algebra_t>> &bounds,
0087 const dtransform3D<algebra_t> &trf, const dpoint3D<algebra_t> &glob_p,
0088 const dscalar<algebra_t> tol =
0089 std::numeric_limits<dscalar<algebra_t>>::epsilon(),
0090 const dscalar<algebra_t> = 0.f) const {
0091
0092 const dpoint3D<algebra_t> loc_p =
0093 cartesian3D<algebra_t>::global_to_local(trf, glob_p, {});
0094
0095
0096 return check_boundaries(
0097 bounds,
0098 dpoint2D<algebra_t>{vector::perp(loc_p),
0099 static_cast<dscalar<algebra_t>>(0.f)},
0100 tol);
0101 }
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112 template <concepts::scalar scalar_t, concepts::point point_t>
0113 DETRAY_HOST_DEVICE constexpr auto check_boundaries(
0114 const bounds_type<scalar_t> &bounds, const point_t &loc_p,
0115 const scalar_t tol = std::numeric_limits<scalar_t>::epsilon(),
0116 const scalar_t = 0.f) const {
0117 return ((loc_p[0] + tol) >= bounds[e_inner_r] &&
0118 loc_p[0] <= (bounds[e_outer_r] + tol));
0119 }
0120
0121
0122
0123
0124
0125
0126
0127 template <concepts::scalar scalar_t>
0128 DETRAY_HOST_DEVICE constexpr scalar_t measure(
0129 const bounds_type<scalar_t> &bounds) const {
0130 return area(bounds);
0131 }
0132
0133
0134
0135
0136
0137
0138 template <concepts::scalar scalar_t>
0139 DETRAY_HOST_DEVICE constexpr scalar_t area(
0140 const bounds_type<scalar_t> &bounds) const {
0141 return (bounds[e_outer_r] * bounds[e_outer_r] -
0142 bounds[e_inner_r] * bounds[e_inner_r]) *
0143 constant<scalar_t>::pi;
0144 }
0145
0146
0147
0148
0149
0150
0151
0152 template <concepts::scalar scalar_t>
0153 DETRAY_HOST_DEVICE constexpr bounds_type<scalar_t> merge(
0154 const bounds_type<scalar_t> &bounds,
0155 const bounds_type<scalar_t> &o_bounds) const {
0156 bounds_type<scalar_t> new_bounds{};
0157
0158 new_bounds[e_inner_r] = math::min(bounds[e_inner_r], o_bounds[e_inner_r]);
0159 new_bounds[e_outer_r] = math::max(bounds[e_outer_r], o_bounds[e_outer_r]);
0160
0161 return new_bounds;
0162 }
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173 template <concepts::algebra algebra_t>
0174 DETRAY_HOST_DEVICE inline darray<dscalar<algebra_t>, 6> local_min_bounds(
0175 const bounds_type<dscalar<algebra_t>> &bounds,
0176 const dscalar<algebra_t> env =
0177 std::numeric_limits<dscalar<algebra_t>>::epsilon()) const {
0178 assert(env > 0.f);
0179 const dscalar<algebra_t> r_bound{env + bounds[e_outer_r]};
0180 return {-r_bound, -r_bound, -env, r_bound, r_bound, env};
0181 }
0182
0183
0184 template <concepts::algebra algebra_t>
0185 DETRAY_HOST_DEVICE dpoint3D<algebra_t> centroid(
0186 const bounds_type<dscalar<algebra_t>> & ) const {
0187 return {0.f, 0.f, 0.f};
0188 }
0189
0190
0191
0192
0193
0194
0195
0196 template <concepts::algebra algebra_t>
0197 DETRAY_HOST dvector<dpoint3D<algebra_t>> vertices(
0198 const bounds_type<dscalar<algebra_t>> & ,
0199 dindex ) const {
0200 throw std::runtime_error("Vertex generation for rings is not implemented");
0201 return {};
0202 }
0203
0204
0205
0206
0207
0208
0209
0210 template <concepts::scalar scalar_t>
0211 DETRAY_HOST constexpr bool check_consistency(
0212 const bounds_type<scalar_t> &bounds, std::ostream &os) const {
0213 constexpr auto tol{10.f * std::numeric_limits<scalar_t>::epsilon()};
0214
0215 if (math::signbit(bounds[e_inner_r]) || bounds[e_outer_r] < tol) {
0216 os << "DETRAY ERROR (HOST): Radius must be in the range [0, "
0217 "numeric_max)"
0218 << std::endl;
0219 return false;
0220 }
0221 if (bounds[e_inner_r] >= bounds[e_outer_r] ||
0222 math::fabs(bounds[e_inner_r] - bounds[e_outer_r]) < tol) {
0223 os << "DETRAY ERROR (HOST): Inner radius must be smaller outer "
0224 "radius.";
0225 return false;
0226 }
0227
0228 return true;
0229 }
0230 };
0231
0232 }