Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-27 07:23:59

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 // Project include(s)
0012 #include "detray/definitions/algebra.hpp"
0013 #include "detray/definitions/indexing.hpp"
0014 #include "detray/geometry/coordinates/coordinates.hpp"
0015 
0016 // System include(s)
0017 #include <concepts>
0018 #include <ostream>
0019 #include <type_traits>
0020 
0021 namespace detray::concepts {
0022 
0023 /// Concept for a type that performs coordinate shape transformations
0024 template <class F>
0025 concept coordinate_frame = requires() {
0026   requires concepts::point<typename F::loc_point>;
0027   requires concepts::algebra<typename F::algebra_type>;
0028 
0029   {
0030     F::global_to_local_3D(dtransform3D<typename F::algebra_type>(),
0031                           dpoint3D<typename F::algebra_type>(),
0032                           dvector3D<typename F::algebra_type>())
0033   } -> std::same_as<dpoint3D<typename F::algebra_type>>;
0034 
0035   {
0036     F::global_to_local(dtransform3D<typename F::algebra_type>(),
0037                        dpoint3D<typename F::algebra_type>(),
0038                        dvector3D<typename F::algebra_type>())
0039   } -> std::same_as<typename F::loc_point>;
0040 
0041   {
0042     F::local_to_global(dtransform3D<typename F::algebra_type>(),
0043                        dpoint3D<typename F::algebra_type>())
0044   } -> std::same_as<dpoint3D<typename F::algebra_type>>;
0045 
0046   {
0047     F::normal(dtransform3D<typename F::algebra_type>(),
0048               dpoint3D<typename F::algebra_type>())
0049   } -> std::same_as<dvector3D<typename F::algebra_type>>;
0050 };
0051 
0052 /// Concept for a geometrical shape
0053 template <typename S, typename A>
0054 concept shape = concepts::algebra<A> && requires(const S sh, std::ostream os) {
0055   requires std::is_enum_v<typename S::boundaries>;
0056 
0057   requires concepts::coordinate_frame<typename S::template local_frame_type<A>>;
0058 
0059   typename S::template result_type<dbool<A>>;
0060   typename S::template bounds_type<dscalar<A>>;
0061 
0062   S::dim;
0063 
0064   {
0065     sh.min_dist_to_boundary(typename S::template bounds_type<dscalar<A>>(),
0066                             dpoint2D<A>())
0067   } -> std::same_as<dscalar<A>>;
0068 
0069   {
0070     sh.template check_boundaries<A>(
0071         typename S::template bounds_type<dscalar<A>>(), dtransform3D<A>(),
0072         dpoint3D<A>(), dscalar<A>())
0073   } -> std::same_as<typename S::template result_type<dbool<A>>>;
0074 
0075   {
0076     sh.measure(typename S::template bounds_type<dscalar<A>>())
0077   } -> std::same_as<dscalar<A>>;
0078 
0079   {
0080     sh.merge(typename S::template bounds_type<dscalar<A>>(),
0081              typename S::template bounds_type<dscalar<A>>())
0082   } -> std::same_as<typename S::template bounds_type<dscalar<A>>>;
0083 
0084   {
0085     sh.template local_min_bounds<A>(
0086         typename S::template bounds_type<dscalar<A>>(), dscalar<A>())
0087   } -> std::same_as<darray<dscalar<A>, 6>>;
0088 
0089   {
0090     sh.template centroid<A>(typename S::template bounds_type<dscalar<A>>())
0091   } -> std::same_as<dpoint3D<A>>;
0092 
0093   {
0094     sh.template vertices<A>(typename S::template bounds_type<dscalar<A>>(),
0095                             dindex())
0096   } -> std::same_as<dvector<dpoint3D<A>>>;
0097 
0098   {
0099     sh.check_consistency(typename S::template bounds_type<dscalar<A>>(), os)
0100   } -> std::same_as<bool>;
0101 };
0102 
0103 /// Definition of a geometric object, that either has a shape or a local frame
0104 /// @{
0105 template <class G>
0106 concept has_shape =
0107     concepts::algebra<typename G::algebra_type> &&
0108     concepts::shape<typename G::shape, typename G::algebra_type>;
0109 
0110 template <class G>
0111 concept has_local_frame = concepts::coordinate_frame<typename G::local_frame>;
0112 
0113 template <class G>
0114 concept geometric_object =
0115     concepts::algebra<typename G::algebra_type> &&
0116     (concepts::has_shape<G> || concepts::has_local_frame<G>);
0117 /// @}
0118 
0119 /// Frame types
0120 /// @{
0121 template <class F>
0122 concept planar_frame =
0123     concepts::coordinate_frame<F> &&
0124     (std::same_as<F, cartesian2D<typename F::algebra_type>> ||
0125      std::same_as<F, polar2D<typename F::algebra_type>>);
0126 
0127 template <class F>
0128 concept rectilinear_frame =
0129     concepts::coordinate_frame<F> &&
0130     (std::same_as<F, cartesian2D<typename F::algebra_type>> ||
0131      std::same_as<F, cartesian3D<typename F::algebra_type>>);
0132 
0133 template <class F>
0134 concept cylindrical_frame =
0135     concepts::coordinate_frame<F> &&
0136     (std::same_as<F, cylindrical2D<typename F::algebra_type>> ||
0137      std::same_as<F, cylindrical3D<typename F::algebra_type>> ||
0138      std::same_as<F, concentric_cylindrical2D<typename F::algebra_type>>);
0139 
0140 template <class F>
0141 concept line_frame = concepts::coordinate_frame<F> &&
0142                      std::same_as<F, line2D<typename F::algebra_type>>;
0143 /// @}
0144 
0145 /// Shape types
0146 /// @{
0147 template <class S, class A>
0148 concept planar_shape =
0149     concepts::shape<S, A> &&
0150     concepts::planar_frame<typename S::template local_frame_type<A>>;
0151 
0152 template <class S, class A>
0153 concept rectilinear_shape =
0154     concepts::shape<S, A> &&
0155     concepts::rectilinear_frame<typename S::template local_frame_type<A>>;
0156 
0157 template <class S, class A>
0158 concept cylindrical_shape =
0159     concepts::shape<S, A> &&
0160     concepts::cylindrical_frame<typename S::template local_frame_type<A>>;
0161 
0162 template <class S, class A>
0163 concept line_shape =
0164     concepts::shape<S, A> &&
0165     concepts::line_frame<typename S::template local_frame_type<A>>;
0166 /// @}
0167 
0168 /// Geometric object types
0169 /// @{
0170 template <class G>
0171 concept planar_object =
0172     (concepts::geometric_object<G>) &&
0173     ((concepts::has_shape<G> &&
0174       concepts::planar_shape<typename G::shape, typename G::algebra_type>) ||
0175      (concepts::has_local_frame<G> &&
0176       concepts::planar_frame<typename G::local_frame>));
0177 
0178 template <class G>
0179 concept rectilinear_object =
0180     (concepts::geometric_object<G>) &&
0181     ((concepts::has_shape<G> &&
0182       concepts::rectilinear_shape<typename G::shape,
0183                                   typename G::algebra_type>) ||
0184      (concepts::has_local_frame<G> &&
0185       concepts::rectilinear_frame<typename G::local_frame>));
0186 
0187 template <class G>
0188 concept cylindrical_object =
0189     (concepts::geometric_object<G>) &&
0190     ((concepts::has_shape<G> &&
0191       concepts::cylindrical_shape<typename G::shape,
0192                                   typename G::algebra_type>) ||
0193      (concepts::has_local_frame<G> &&
0194       concepts::cylindrical_frame<typename G::local_frame>));
0195 
0196 template <class G>
0197 concept line_object =
0198     (concepts::geometric_object<G>) &&
0199     ((concepts::has_shape<G> &&
0200       concepts::line_shape<typename G::shape, typename G::algebra_type>) ||
0201      (concepts::has_local_frame<G> &&
0202       concepts::line_frame<typename G::local_frame>));
0203 /// @}
0204 
0205 // TODO: Add shape concepts here, which however depend on the algebra type
0206 template <class T>
0207 concept planar = concepts::planar_frame<T> || concepts::planar_object<T>;
0208 
0209 template <class T>
0210 concept rectilinear =
0211     concepts::rectilinear_frame<T> || concepts::rectilinear_object<T>;
0212 
0213 template <class T>
0214 concept cylindrical =
0215     concepts::cylindrical_frame<T> || concepts::cylindrical_object<T>;
0216 
0217 template <class T>
0218 concept line = concepts::line_frame<T> || concepts::line_object<T>;
0219 
0220 }  // namespace detray::concepts