|
||||
File indexing completed on 2025-01-18 10:05:56
0001 //----------------------------------*-C++-*----------------------------------// 0002 // Copyright 2024 UT-Battelle, LLC, and other Celeritas developers. 0003 // See the top-level COPYRIGHT file for details. 0004 // SPDX-License-Identifier: (Apache-2.0 OR MIT) 0005 //---------------------------------------------------------------------------// 0006 //! \file orange/orangeinp/Solid.hh 0007 //---------------------------------------------------------------------------// 0008 #pragma once 0009 0010 #include <optional> 0011 #include <type_traits> 0012 #include <utility> 0013 0014 #include "corecel/math/Turn.hh" 0015 0016 #include "IntersectRegion.hh" 0017 #include "ObjectInterface.hh" 0018 0019 namespace celeritas 0020 { 0021 namespace orangeinp 0022 { 0023 //---------------------------------------------------------------------------// 0024 /*! 0025 * Define the angular region of a solid. 0026 * 0027 * This is a pie slice infinite along the z axis and outward from it. Its cross 0028 * section is in the \em x-y plane, and a start 0029 * angle of zero corresponding to the \em +x axis. An interior angle of one 0030 * results in no radial excluded in the resulting solid. A interior angle of 0031 * more than 0.5 turns (180 degrees) results in a wedge being subtracted from 0032 * the solid, and an angle of less than or equal to 0.5 turns results in the 0033 * intersection of the solid with a wedge. 0034 * 0035 * \code 0036 // Truncates a solid to the east-facing quadrant: 0037 SolidEnclosedAngle{Turn{-0.125}, Turn{0.25}}; 0038 // Removes the second quadrant (northwest) from a solid: 0039 SolidEnclosedAngle{Turn{0.50}, Turn{0.75}}; 0040 \endcode 0041 */ 0042 class SolidEnclosedAngle 0043 { 0044 public: 0045 //!@{ 0046 //! \name Type aliases 0047 using SenseWedge = std::pair<Sense, InfWedge>; 0048 //!@} 0049 0050 public: 0051 //! Default to "all angles" 0052 SolidEnclosedAngle() = default; 0053 0054 // Construct from a starting angle and interior angle 0055 SolidEnclosedAngle(Turn start, Turn interior); 0056 0057 // Construct a wedge shape to intersect (inside) or subtract (outside) 0058 SenseWedge make_wedge() const; 0059 0060 // Whether the enclosed angle is not a full circle 0061 explicit inline operator bool() const; 0062 0063 //! Starting angle 0064 Turn start() const { return start_; } 0065 0066 //! Interior angle 0067 Turn interior() const { return interior_; } 0068 0069 private: 0070 Turn start_{0}; 0071 Turn interior_{1}; 0072 }; 0073 0074 //---------------------------------------------------------------------------// 0075 /*! 0076 * A hollow shape with an optional start and end angle. 0077 * 0078 * Solids are a shape with (optionally) the same *kind* of shape subtracted 0079 * from it, and (optionally) an azimuthal section removed from it. 0080 */ 0081 class SolidBase : public ObjectInterface 0082 { 0083 public: 0084 // Construct a volume from this object 0085 NodeId build(VolumeBuilder&) const final; 0086 0087 // Write the shape to JSON 0088 void output(JsonPimpl*) const final; 0089 0090 //! Interior intersect region interface for construction and access 0091 virtual IntersectRegionInterface const& interior() const = 0; 0092 0093 //! Optional excluded region 0094 virtual IntersectRegionInterface const* excluded() const = 0; 0095 0096 //! Optional azimuthal angular restriction 0097 virtual SolidEnclosedAngle enclosed_angle() const = 0; 0098 0099 protected: 0100 //!@{ 0101 //! Allow construction and assignment only through daughter classes 0102 SolidBase() = default; 0103 virtual ~SolidBase() = default; 0104 CELER_DEFAULT_COPY_MOVE(SolidBase); 0105 //!@} 0106 }; 0107 0108 //---------------------------------------------------------------------------// 0109 /*! 0110 * A shape that is hollow, is truncated azimuthally, or both. 0111 * 0112 * Examples: \code 0113 // A cone with a thickness of 0.1 0114 Solid s{"cone", Cone{{1, 2}, 10.0}, Cone{{0.9, 1.9}, 10.0}}; 0115 // A cylinder segment in z={-2.5, 2.5}, r={0.5, 0.75}, theta={-45, 45} deg 0116 Solid s{"cyl", Cylinder{0.75, 5.0}, Cylinder{0.5, 5.0}, 0117 {Turn{0}, Turn{0.25}}; 0118 // The east-facing quarter of a cone shape 0119 Solid s{"cone", Cone{{1, 2}, 10.0}, {Turn{-0.125}, Turn{0.25}}; 0120 * \endcode 0121 */ 0122 template<class T> 0123 class Solid final : public SolidBase 0124 { 0125 static_assert(std::is_base_of_v<IntersectRegionInterface, T>); 0126 0127 public: 0128 //!@{ 0129 //! \name Type aliases 0130 using OptionalRegion = std::optional<T>; 0131 //!@} 0132 0133 public: 0134 // Return a solid *or* shape given an optional interior or enclosed angle 0135 static SPConstObject or_shape(std::string&& label, 0136 T&& interior, 0137 OptionalRegion&& excluded, 0138 SolidEnclosedAngle&& enclosed); 0139 0140 // Construct with an excluded interior *and/or* enclosed angle 0141 Solid(std::string&& label, 0142 T&& interior, 0143 OptionalRegion&& excluded, 0144 SolidEnclosedAngle&& enclosed); 0145 0146 // Construct with only an enclosed angle 0147 Solid(std::string&& label, T&& interior, SolidEnclosedAngle&& enclosed); 0148 0149 // Construct with only an excluded interior 0150 Solid(std::string&& label, T&& interior, T&& excluded); 0151 0152 //! Get the user-provided label 0153 std::string_view label() const final { return label_; } 0154 0155 //! Interior intersect region interface for construction and access 0156 IntersectRegionInterface const& interior() const final 0157 { 0158 return interior_; 0159 } 0160 0161 // Optional excluded 0162 IntersectRegionInterface const* excluded() const final; 0163 0164 //! Optional angular restriction 0165 SolidEnclosedAngle enclosed_angle() const final { return enclosed_; } 0166 0167 private: 0168 std::string label_; 0169 T interior_; 0170 OptionalRegion exclusion_; 0171 SolidEnclosedAngle enclosed_; 0172 }; 0173 0174 //---------------------------------------------------------------------------// 0175 // DEDUCTION GUIDES 0176 //---------------------------------------------------------------------------// 0177 0178 template<class T, class... Us> 0179 Solid(std::string&&, T&&, Us...) -> Solid<T>; 0180 0181 //---------------------------------------------------------------------------// 0182 // TYPE ALIASES 0183 //---------------------------------------------------------------------------// 0184 0185 using ConeSolid = Solid<Cone>; 0186 using CylinderSolid = Solid<Cylinder>; 0187 using PrismSolid = Solid<Prism>; 0188 using SphereSolid = Solid<Sphere>; 0189 0190 //---------------------------------------------------------------------------// 0191 // EXPLICIT INSTANTIATION 0192 //---------------------------------------------------------------------------// 0193 0194 extern template class Solid<Cone>; 0195 extern template class Solid<Cylinder>; 0196 extern template class Solid<Prism>; 0197 extern template class Solid<Sphere>; 0198 0199 //---------------------------------------------------------------------------// 0200 // INLINE DEFINITIONS 0201 //---------------------------------------------------------------------------// 0202 /*! 0203 * Whether the enclosed angle is not a full circle. 0204 */ 0205 SolidEnclosedAngle::operator bool() const 0206 { 0207 return interior_ != Turn{1}; 0208 } 0209 0210 //---------------------------------------------------------------------------// 0211 /*! 0212 * Access the optional excluded. 0213 */ 0214 template<class T> 0215 IntersectRegionInterface const* Solid<T>::excluded() const 0216 { 0217 return exclusion_ ? &(*exclusion_) : nullptr; 0218 } 0219 0220 //---------------------------------------------------------------------------// 0221 } // namespace orangeinp 0222 } // 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 |