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