![]() |
|
|||
File indexing completed on 2025-09-16 09:03:17
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/orangeinp/Solid.hh 0006 //---------------------------------------------------------------------------// 0007 #pragma once 0008 0009 #include <optional> 0010 #include <type_traits> 0011 #include <utility> 0012 0013 #include "corecel/math/Turn.hh" 0014 0015 #include "IntersectRegion.hh" 0016 #include "ObjectInterface.hh" 0017 0018 namespace celeritas 0019 { 0020 namespace orangeinp 0021 { 0022 //---------------------------------------------------------------------------// 0023 /*! 0024 * Define the angular region of a solid. 0025 * 0026 * This is a pie slice infinite along the z axis and outward from it. Its cross 0027 * section is in the \em x-y plane, and a start 0028 * angle of zero corresponding to the \em +x axis. An interior angle of one 0029 * results in no radial excluded in the resulting solid. A interior angle of 0030 * more than 0.5 turns (180 degrees) results in a wedge being subtracted from 0031 * the solid, and an angle of less than or equal to 0.5 turns results in the 0032 * intersection of the solid with a wedge. 0033 * 0034 * \code 0035 // Truncates a solid to the east-facing quadrant: 0036 SolidEnclosedAngle{Turn{-0.125}, Turn{0.25}}; 0037 // Removes the second quadrant (northwest) from a solid: 0038 SolidEnclosedAngle{Turn{0.50}, Turn{0.75}}; 0039 \endcode 0040 */ 0041 class SolidEnclosedAngle 0042 { 0043 public: 0044 //!@{ 0045 //! \name Type aliases 0046 using SenseWedge = std::pair<Sense, InfWedge>; 0047 //!@} 0048 0049 public: 0050 //! Default to "all angles" 0051 SolidEnclosedAngle() = default; 0052 0053 // Construct from a starting angle and interior angle 0054 SolidEnclosedAngle(Turn start, Turn interior); 0055 0056 // Construct a wedge shape to intersect (inside) or subtract (outside) 0057 SenseWedge make_wedge() const; 0058 0059 // Whether the enclosed angle is not a full circle 0060 explicit inline operator bool() const; 0061 0062 //! Starting angle 0063 Turn start() const { return start_; } 0064 0065 //! Interior angle 0066 Turn interior() const { return interior_; } 0067 0068 private: 0069 Turn start_{0}; 0070 Turn interior_{1}; 0071 }; 0072 0073 //---------------------------------------------------------------------------// 0074 /*! 0075 * Define a slab that is bound by the top/bottom z-cuts of the solid. 0076 */ 0077 class SolidZSlab 0078 { 0079 public: 0080 //! Default to all space 0081 SolidZSlab() = default; 0082 0083 // Construct from lower and upper z-plane 0084 SolidZSlab(real_type lower, real_type upper); 0085 0086 // Construct an InfSlab shape to intersect with the solid 0087 InfSlab make_inf_slab() const; 0088 0089 // Whether the z-slab is finite in z. 0090 explicit inline operator bool() const; 0091 0092 //! Lower z-plane 0093 real_type lower() const { return lower_; } 0094 0095 //! Upper z-plane 0096 real_type upper() const { return upper_; } 0097 0098 private: 0099 real_type lower_{-std::numeric_limits<real_type>::infinity()}; 0100 real_type upper_{std::numeric_limits<real_type>::infinity()}; 0101 }; 0102 0103 //---------------------------------------------------------------------------// 0104 /*! 0105 * A hollow shape with an optional start and end angle. 0106 * 0107 * Solids are a shape with (optionally) the same *kind* of shape subtracted 0108 * from it, and (optionally) an azimuthal section removed from it. 0109 */ 0110 class SolidBase : public ObjectInterface 0111 { 0112 public: 0113 // Construct a volume from this object 0114 NodeId build(VolumeBuilder&) const final; 0115 0116 // Write the shape to JSON 0117 void output(JsonPimpl*) const final; 0118 0119 //! Interior intersect region interface for construction and access 0120 virtual IntersectRegionInterface const& interior() const = 0; 0121 0122 //! Optional excluded region 0123 virtual IntersectRegionInterface const* excluded() const = 0; 0124 0125 //! Optional azimuthal angular restriction 0126 virtual SolidEnclosedAngle enclosed_angle() const = 0; 0127 0128 //! Optional z-slab restriction 0129 virtual SolidZSlab z_slab() const = 0; 0130 0131 ~SolidBase() override = default; 0132 0133 protected: 0134 //!@{ 0135 //! Allow construction and assignment only through daughter classes 0136 SolidBase() = default; 0137 CELER_DEFAULT_COPY_MOVE(SolidBase); 0138 //!@} 0139 }; 0140 0141 //---------------------------------------------------------------------------// 0142 /*! 0143 * A shape that has undergone an intersection or combination of intersections. 0144 * 0145 * This shape may be: 0146 * A) hollow (exluded interior), 0147 * B) truncated azimuthally (enclosed angle), 0148 * C) truncated in z (intersected with z-slab), 0149 * D) both A and B. 0150 * 0151 * Examples: \code 0152 // A cone with a thickness of 0.1 0153 Solid s{"cone", Cone{{1, 2}, 10.0}, Cone{{0.9, 1.9}, 10.0}}; 0154 // A cylinder segment in z={-2.5, 2.5}, r={0.5, 0.75}, theta={-45, 45} deg 0155 Solid s{"cyl", Cylinder{0.75, 5.0}, Cylinder{0.5, 5.0}, 0156 {Turn{0}, Turn{0.25}}; 0157 // The east-facing quarter of a cone shape 0158 Solid s{"cone", Cone{{1, 2}, 10.0}, {Turn{-0.125}, Turn{0.25}}; 0159 * \endcode 0160 */ 0161 template<class T> 0162 class Solid final : public SolidBase 0163 { 0164 static_assert(std::is_base_of_v<IntersectRegionInterface, T>); 0165 0166 public: 0167 //!@{ 0168 //! \name Type aliases 0169 using OptionalRegion = std::optional<T>; 0170 //!@} 0171 0172 public: 0173 // Return a solid *or* shape given an optional interior or enclosed angle 0174 static SPConstObject or_shape(std::string&& label, 0175 T&& interior, 0176 OptionalRegion&& excluded, 0177 SolidEnclosedAngle&& enclosed); 0178 0179 // Construct with an excluded interior *and/or* enclosed angle 0180 Solid(std::string&& label, 0181 T&& interior, 0182 OptionalRegion&& excluded, 0183 SolidEnclosedAngle&& enclosed); 0184 0185 // Construct with only an enclosed angle 0186 Solid(std::string&& label, T&& interior, SolidEnclosedAngle&& enclosed); 0187 0188 // Construct with only an excluded interior 0189 Solid(std::string&& label, T&& interior, T&& excluded); 0190 0191 // Construct with only a z-slab 0192 Solid(std::string&& label, T&& interior, SolidZSlab&& z_slab); 0193 0194 //! Get the user-provided label 0195 std::string_view label() const final { return label_; } 0196 0197 //! Interior intersect region interface for construction and access 0198 IntersectRegionInterface const& interior() const final 0199 { 0200 return interior_; 0201 } 0202 0203 // Optional excluded 0204 IntersectRegionInterface const* excluded() const final; 0205 0206 //! Optional angular restriction 0207 SolidEnclosedAngle enclosed_angle() const final { return enclosed_; } 0208 0209 //! Optional z-slab intersection 0210 SolidZSlab z_slab() const final { return z_slab_; } 0211 0212 private: 0213 std::string label_; 0214 T interior_; 0215 OptionalRegion exclusion_; 0216 SolidEnclosedAngle enclosed_; 0217 SolidZSlab z_slab_; 0218 }; 0219 0220 //---------------------------------------------------------------------------// 0221 // DEDUCTION GUIDES 0222 //---------------------------------------------------------------------------// 0223 0224 template<class T, class... Us> 0225 Solid(std::string&&, T&&, Us...) -> Solid<T>; 0226 0227 //---------------------------------------------------------------------------// 0228 // TYPE ALIASES 0229 //---------------------------------------------------------------------------// 0230 0231 using ConeSolid = Solid<Cone>; 0232 using CylinderSolid = Solid<Cylinder>; 0233 using PrismSolid = Solid<Prism>; 0234 using SphereSolid = Solid<Sphere>; 0235 using EllipsoidSolid = Solid<Ellipsoid>; 0236 0237 //---------------------------------------------------------------------------// 0238 // EXPLICIT INSTANTIATION 0239 //---------------------------------------------------------------------------// 0240 0241 extern template class Solid<Cone>; 0242 extern template class Solid<Cylinder>; 0243 extern template class Solid<Prism>; 0244 extern template class Solid<Sphere>; 0245 extern template class Solid<Ellipsoid>; 0246 0247 //---------------------------------------------------------------------------// 0248 // INLINE DEFINITIONS 0249 //---------------------------------------------------------------------------// 0250 /*! 0251 * Whether the enclosed angle is not a full circle. 0252 */ 0253 SolidEnclosedAngle::operator bool() const 0254 { 0255 return interior_ != Turn{1}; 0256 } 0257 0258 //---------------------------------------------------------------------------// 0259 /*! 0260 * Whether the z-slab is finite in z. 0261 */ 0262 SolidZSlab::operator bool() const 0263 { 0264 return std::isfinite(lower_) || std::isfinite(upper_); 0265 } 0266 0267 //---------------------------------------------------------------------------// 0268 /*! 0269 * Access the optional excluded. 0270 */ 0271 template<class T> 0272 IntersectRegionInterface const* Solid<T>::excluded() const 0273 { 0274 return exclusion_ ? &(*exclusion_) : nullptr; 0275 } 0276 0277 //---------------------------------------------------------------------------// 0278 } // namespace orangeinp 0279 } // namespace celeritas
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |