![]() |
|
|||
File indexing completed on 2025-09-18 09:24:54
0001 //------------------------------- -*- C++ -*- -------------------------------// 0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details 0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT) 0004 //---------------------------------------------------------------------------// 0005 //! \file orange/OrangeTypes.hh 0006 //! \brief Type definitions for ORANGE geometry. 0007 //---------------------------------------------------------------------------// 0008 #pragma once 0009 0010 #include <cstddef> 0011 #include <functional> 0012 #include <type_traits> 0013 0014 #include "corecel/Macros.hh" 0015 #include "corecel/OpaqueId.hh" 0016 #include "corecel/Types.hh" 0017 #include "corecel/cont/Array.hh" 0018 #include "corecel/math/NumericLimits.hh" 0019 #include "geocel/Types.hh" // IWYU pragma: export 0020 0021 namespace celeritas 0022 { 0023 //---------------------------------------------------------------------------// 0024 template<class T> 0025 class BoundingBox; 0026 0027 //---------------------------------------------------------------------------// 0028 // TYPE ALIASES 0029 //---------------------------------------------------------------------------// 0030 0031 //! Real type used for acceleration 0032 using fast_real_type = float; 0033 0034 //! Integer type for volume CSG tree representation 0035 using logic_int = size_type; 0036 0037 //! Helper class for some template dispatch functions 0038 template<Axis T> 0039 using AxisTag = std::integral_constant<Axis, T>; 0040 0041 //// ID TYPES //// 0042 0043 //! Identifier for a BIHNode objects 0044 using BIHNodeId = OpaqueId<struct BIHNode_>; 0045 0046 //! Identifier for a daughter universe 0047 using DaughterId = OpaqueId<struct Daughter>; 0048 0049 //! Identifier for a face within a volume 0050 using FaceId = OpaqueId<struct Face_, logic_int>; 0051 0052 //! Bounding box used for acceleration 0053 using FastBBox = BoundingBox<fast_real_type>; 0054 0055 //! Identifier for a bounding box used for acceleration 0056 using FastBBoxId = OpaqueId<FastBBox>; 0057 0058 //! Identifier for an array of length three of floating point values 0059 using FastReal3 = Array<float, 3>; 0060 0061 //! Local identifier for a surface within a universe 0062 using LocalSurfaceId = OpaqueId<struct LocalSurface_>; 0063 0064 //! Local identifier for a geometry volume within a universe 0065 using LocalVolumeId = OpaqueId<struct LocalVolume_>; 0066 0067 //! Identifier for an OrientedBoundingZone 0068 using OrientedBoundingZoneId = OpaqueId<struct OrientedBoundingZoneRecord>; 0069 0070 //! Opaque index for "simple unit" data 0071 using SimpleUnitId = OpaqueId<struct SimpleUnitRecord>; 0072 0073 //! Opaque index for rectilinear array data 0074 using RectArrayId = OpaqueId<struct RectArrayRecord>; 0075 0076 //! Identifier for a translation of a single embedded universe 0077 using TransformId = OpaqueId<struct TransformRecord>; 0078 0079 //! Identifier for a relocatable set of volumes 0080 using UniverseId = OpaqueId<struct Universe_>; 0081 0082 //---------------------------------------------------------------------------// 0083 // ENUMERATIONS 0084 //---------------------------------------------------------------------------// 0085 /*! 0086 * Whether a position is logically "inside" or "outside" a surface. 0087 * 0088 * For a plane, "outside" (true) is the "positive" sense and equivalent to 0089 * \f[ 0090 \vec x \cdot \vec n >= 0 0091 * \f] 0092 * and "inside" is to the left of the plane's normal. Likewise, for a 0093 * sphere, "inside" is where the dot product of the position and outward normal 0094 * is negative. 0095 */ 0096 enum class Sense : bool 0097 { 0098 inside, //!< Quadric expression is less than zero 0099 outside, //!< Expression is greater than zero 0100 }; 0101 0102 //---------------------------------------------------------------------------// 0103 /*! 0104 * Enumeration for mapping surface classes to integers. 0105 * 0106 * These are ordered roughly by complexity. The storage requirement for 0107 * corresponding surfaces are: 0108 * - 1 for `p.|sc|c.c`, 0109 * - 3 for `c.`, 0110 * - 4 for `[ps]|k.`, 0111 * - 7 for `sq`, and 0112 * - 10 for `gq`. 0113 * 0114 * See \c orange/surf/SurfaceTypeTraits.hh for how these map to classes. 0115 */ 0116 enum class SurfaceType : unsigned char 0117 { 0118 px, //!< Plane aligned with X axis 0119 py, //!< Plane aligned with Y axis 0120 pz, //!< Plane aligned with Z axis 0121 cxc, //!< Cylinder centered on X axis 0122 cyc, //!< Cylinder centered on Y axis 0123 czc, //!< Cylinder centered on Z axis 0124 sc, //!< Sphere centered at the origin 0125 cx, //!< Cylinder parallel to X axis 0126 cy, //!< Cylinder parallel to Y axis 0127 cz, //!< Cylinder parallel to Z axis 0128 p, //!< General plane 0129 s, //!< Sphere 0130 kx, //!< Cone parallel to X axis 0131 ky, //!< Cone parallel to Y axis 0132 kz, //!< Cone parallel to Z axis 0133 sq, //!< Simple quadric 0134 gq, //!< General quadric 0135 inv, //!< Involute 0136 size_ //!< Sentinel value for number of surface types 0137 }; 0138 0139 //---------------------------------------------------------------------------// 0140 /*! 0141 * Enumeration for mapping transform implementations to integers. 0142 */ 0143 enum class TransformType : unsigned char 0144 { 0145 no_transformation, //!< Identity transform 0146 translation, //!< Translation only 0147 transformation, //!< Translation plus rotation 0148 size_ 0149 }; 0150 0151 //---------------------------------------------------------------------------// 0152 /*! 0153 * Enumeration for type-deleted universe storage. 0154 * 0155 * See \c orange/univ/UniverseTypeTraits.hh for how these map to data and 0156 * classes. 0157 */ 0158 enum class UniverseType : unsigned char 0159 { 0160 simple, 0161 rect_array, 0162 #if 0 0163 hex_array, 0164 dode_array, 0165 ... 0166 #endif 0167 size_ //!< Sentinel value for number of universe types 0168 }; 0169 0170 //---------------------------------------------------------------------------// 0171 /*! 0172 * Evaluated quadric expression allowing for distinct 'on surface' state. 0173 * 0174 * For a plane, "outside" is equivalent to 0175 * \f[ 0176 \vec x \cdot \vec n > 0 0177 * \f] 0178 * and "inside" is to the left of the plane's normal (a negative dot product). 0179 * The exact equality to zero is literally an "edge case" but it can happen 0180 * with inter-universe coincident surfaces as well as carefully placed 0181 * particle sources and ray tracing. 0182 * 0183 * As an implementataion detail, the "on" case is currently *exact*, but future 0184 * changes might increase the width of "on" to a finite but small range 0185 * ("fuzziness"). 0186 */ 0187 enum class SignedSense 0188 { 0189 inside = -1, 0190 on = 0, 0191 outside = 1 0192 }; 0193 0194 //---------------------------------------------------------------------------// 0195 /*! 0196 * When evaluating an intersection, whether the point is on the surface. 0197 * 0198 * This helps eliminate roundoff errors and other arithmetic issues. 0199 */ 0200 enum class SurfaceState : bool 0201 { 0202 off = false, 0203 on = true 0204 }; 0205 0206 //---------------------------------------------------------------------------// 0207 /*! 0208 * When crossing a boundary, whether the track exits the current volume. 0209 * 0210 * This is necessary due to changes in direction on the boundary due to 0211 * magnetic field and/or multiple scattering. We could extend this later to a 0212 * flag set of "volume changed" (internal non-reflective crossing), "direction 0213 * changed" (reflecting/periodic), "position changed" (bump/periodic). 0214 */ 0215 enum class BoundaryResult : bool 0216 { 0217 reentrant = false, 0218 exiting = true 0219 }; 0220 0221 //---------------------------------------------------------------------------// 0222 /*! 0223 * Chirality of a twirly object (currently only Involute). 0224 */ 0225 enum class Chirality : bool 0226 { 0227 left, //!< Sinistral, spiraling counterclockwise 0228 right, //!< Dextral, spiraling clockwise 0229 }; 0230 0231 //---------------------------------------------------------------------------// 0232 /*! 0233 * Volume logic encoding. 0234 * 0235 * This uses an *unscoped* enum inside a *namespace* so that its values can be 0236 * freely intermingled with other integers that represent face IDs. 0237 */ 0238 namespace logic 0239 { 0240 //! Special logical Evaluator tokens ordered by precedence. 0241 // The enum values are set to the highest 6 values of logic_int. 0242 enum OperatorToken : logic_int 0243 { 0244 lbegin = logic_int(~logic_int(6)), 0245 lopen = lbegin, //!< Open parenthesis 0246 lclose, //!< Close parenthesis 0247 lor, //!< Binary logical OR 0248 land, //!< Binary logical AND 0249 lnot, //!< Unary negation 0250 ltrue, //!< Push 'true' 0251 lend 0252 }; 0253 } // namespace logic 0254 0255 //---------------------------------------------------------------------------// 0256 /*! 0257 * Masking priority. 0258 * 0259 * This is currently not implemented in GPU ORANGE except for the special 0260 * "background" cell and "exterior". 0261 */ 0262 enum class ZOrder : size_type 0263 { 0264 invalid = 0, //!< Invalid region 0265 background, //!< Implicit fill 0266 media, //!< Material-filled region or array 0267 array, //!< Lattice array of nested arrangement 0268 hole, //!< Another universe masking this one 0269 implicit_exterior = size_type(-2), //!< Exterior in lower universe 0270 exterior = size_type(-1), //!< The global problem boundary 0271 }; 0272 0273 //---------------------------------------------------------------------------// 0274 // STRUCTS 0275 //---------------------------------------------------------------------------// 0276 /*! 0277 * Data specifying a daughter universe embedded in a volume. 0278 */ 0279 struct Daughter 0280 { 0281 UniverseId universe_id; 0282 TransformId trans_id; 0283 }; 0284 0285 //---------------------------------------------------------------------------// 0286 /*! 0287 * Tolerance for construction and runtime bumping. 0288 * 0289 * The relative error is used for comparisons of magnitudes of values, and the 0290 * absolute error provides a lower bound for the comparison tolerance. In most 0291 * cases (see \c SoftEqual, \c BoundingBoxBumper , \c detail::BumpCalculator) 0292 * the tolerance used is a maximum of the absolute error and the 1- or 2-norm 0293 * of some spatial coordinate. In other cases (\c SurfaceSimplifier, \c 0294 * SoftSurfaceEqual) the similarity between surfaces is determined by solving 0295 * for a change in surface coefficients that results in no more than a change 0296 * in \f$ \epsilon \f$ of a particle intercept. A final special case (the \c 0297 * sqrt_quadratic static variable) is used to approximate the degenerate 0298 * condition \f$ a\sim 0\f$ for a particle traveling nearly parallel to a 0299 * quadric surface: see \c CylAligned for a discussion. 0300 * 0301 * The absolute error should typically be constructed from the relative error 0302 * (since computers use floating point precision) and a characteristic length 0303 * scale for the problem being used. For detector/reactor problems the length 0304 * might be ~1 cm, for microbiology it might be ~1 um, and for astronomy might 0305 * be ~1e6 m. 0306 * 0307 * \note For historical reasons, the absolute tolerance used by \c SoftEqual 0308 * defaults to 1/100 of the relative tolerance, whereas with \c Tolerance the 0309 * equivalent behavior is setting a length scale of 0.01. 0310 * 0311 * \todo Move this to a separate file. 0312 */ 0313 template<class T = ::celeritas::real_type> 0314 struct Tolerance 0315 { 0316 using real_type = T; 0317 0318 real_type rel{}; //!< Relative error for differences 0319 real_type abs{}; //!< Absolute error [native length] 0320 0321 //! Intercept tolerance for parallel-to-quadric cases 0322 static CELER_CONSTEXPR_FUNCTION real_type sqrt_quadratic() 0323 { 0324 if constexpr (std::is_same_v<real_type, double>) 0325 return 1e-5; 0326 else if constexpr (std::is_same_v<real_type, float>) 0327 return 5e-2f; 0328 } 0329 0330 //! True if tolerances are valid 0331 CELER_CONSTEXPR_FUNCTION operator bool() const 0332 { 0333 return rel > 0 && rel < 1 && abs > 0; 0334 } 0335 0336 // Construct from the default relative tolerance (sqrt(precision)) 0337 static Tolerance from_default(real_type length = 1); 0338 0339 // Construct from the default "soft equivalence" relative tolerance 0340 static Tolerance from_softequal(); 0341 0342 // Construct from a relative tolerance and a length scale 0343 static Tolerance from_relative(real_type rel, real_type length = 1); 0344 }; 0345 0346 extern template struct Tolerance<float>; 0347 extern template struct Tolerance<double>; 0348 0349 //---------------------------------------------------------------------------// 0350 // HELPER FUNCTIONS (HOST/DEVICE) 0351 //---------------------------------------------------------------------------// 0352 /*! 0353 * Change whether a boundary crossing is reentrant or exiting. 0354 */ 0355 [[nodiscard]] CELER_CONSTEXPR_FUNCTION BoundaryResult 0356 flip_boundary(BoundaryResult orig) 0357 { 0358 return static_cast<BoundaryResult>(!static_cast<bool>(orig)); 0359 } 0360 0361 //---------------------------------------------------------------------------// 0362 /*! 0363 * Sentinel value indicating "no intersection". 0364 * 0365 * \todo There is probably a better place to put this since it's not a "type". 0366 * \todo A value of zero might also work since zero-length steps are 0367 * prohibited. But we'll need custom `min` and `min_element` in that case. 0368 */ 0369 CELER_CONSTEXPR_FUNCTION real_type no_intersection() 0370 { 0371 return numeric_limits<real_type>::infinity(); 0372 } 0373 0374 //---------------------------------------------------------------------------// 0375 /*! 0376 * Return the UniverseId of the highest-level (i.e., root) universe. 0377 */ 0378 CELER_CONSTEXPR_FUNCTION UniverseId top_universe_id() 0379 { 0380 return UniverseId{0}; 0381 } 0382 0383 //---------------------------------------------------------------------------// 0384 namespace logic 0385 { 0386 //! Whether an integer is a special logic token. 0387 CELER_CONSTEXPR_FUNCTION bool is_operator_token(logic_int lv) 0388 { 0389 return (lv >= lbegin); 0390 } 0391 } // namespace logic 0392 0393 //---------------------------------------------------------------------------// 0394 // HELPER FUNCTIONS (HOST) 0395 //---------------------------------------------------------------------------// 0396 // Get a string corresponding to a surface type 0397 char const* to_cstring(SurfaceType); 0398 0399 // Get a string corresponding to a transform type 0400 char const* to_cstring(TransformType); 0401 0402 // Get a string corresponding to a surface state 0403 inline char const* to_cstring(SurfaceState s) 0404 { 0405 return s == SurfaceState::off ? "off" : "on"; 0406 } 0407 0408 //! Get a printable character corresponding to an operator. 0409 namespace logic 0410 { 0411 inline constexpr char to_char(OperatorToken tok) 0412 { 0413 return is_operator_token(tok) ? "()|&~*"[tok - lbegin] : '\a'; 0414 } 0415 } // namespace logic 0416 0417 // Get a string corresponding to a z ordering 0418 char const* to_cstring(ZOrder); 0419 0420 // Get a printable character corresponding to a z ordering 0421 char to_char(ZOrder z); 0422 0423 // Convert a printable character to a z ordering 0424 ZOrder to_zorder(char c); 0425 0426 //---------------------------------------------------------------------------// 0427 } // namespace celeritas 0428 0429 //---------------------------------------------------------------------------// 0430 // STD::HASH SPECIALIZATION FOR HOST CODE 0431 //---------------------------------------------------------------------------// 0432 //! \cond 0433 namespace std 0434 { 0435 //! Specialization for std::hash for unordered storage. 0436 template<> 0437 struct hash<celeritas::Sense> 0438 { 0439 using argument_type = celeritas::Sense; 0440 using result_type = std::size_t; 0441 result_type operator()(argument_type const& sense) const noexcept 0442 { 0443 return std::hash<bool>()(static_cast<bool>(sense)); 0444 } 0445 }; 0446 } // namespace std 0447 //! \endcond
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |