Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-14 09:01:28

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/PolySolid.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <vector>
0010 
0011 #include "corecel/OpaqueId.hh"
0012 
0013 #include "IntersectRegion.hh"
0014 #include "ObjectInterface.hh"
0015 #include "Solid.hh"
0016 
0017 namespace celeritas
0018 {
0019 namespace orangeinp
0020 {
0021 //---------------------------------------------------------------------------//
0022 /*!
0023  * Radial extents and axial segments for a stacked solid.
0024  *
0025  * Axial grid points must be nondecreasing. If "inner" points are specified,
0026  * they must be less than the outer points and more than zero. The inner list
0027  * is allowed to be empty indicating no inner (hollow) exclusion.
0028  */
0029 class PolySegments
0030 {
0031   public:
0032     //!@{
0033     //! \name Type aliases
0034     using VecReal = std::vector<real_type>;
0035     //!@}
0036 
0037   public:
0038     // Construct from a filled polygon solid
0039     PolySegments(VecReal&& outer, VecReal&& z);
0040 
0041     // Construct from a shell of a polygon solid
0042     PolySegments(VecReal&& inner, VecReal&& outer, VecReal&& z);
0043 
0044     //! Number of segments (one less than grid points)
0045     size_type size() const { return outer_.size() - 1; }
0046 
0047     // Access the inner radii (for building 'exclusion' shape)
0048     inline VecReal const& inner() const;
0049 
0050     //! Access the outer radii (for building 'interior' shape)
0051     VecReal const& outer() const { return outer_; }
0052 
0053     //! Access the z planes
0054     VecReal const& z() const { return z_; }
0055 
0056     // Access lo/hi inner/exclusion radii for a segment
0057     inline Real2 inner(size_type) const;
0058 
0059     // Access lo/hi outer radii for a segment
0060     inline Real2 outer(size_type) const;
0061 
0062     // Access lo/hi z values for a segment
0063     inline Real2 z(size_type) const;
0064 
0065     //! Whether there is an internal subtraction from the poly
0066     bool has_exclusion() const { return !inner_.empty(); }
0067 
0068   private:
0069     VecReal inner_;
0070     VecReal outer_;
0071     VecReal z_;
0072 };
0073 
0074 //---------------------------------------------------------------------------//
0075 /*!
0076  * Access the inner radii (for building 'exclusion' shape).
0077  */
0078 auto PolySegments::inner() const -> VecReal const&
0079 {
0080     CELER_EXPECT(has_exclusion());
0081     return inner_;
0082 }
0083 
0084 //---------------------------------------------------------------------------//
0085 /*!
0086  * Access lo/hi inner/exclusion radii for a segment.
0087  */
0088 auto PolySegments::inner(size_type i) const -> Real2
0089 {
0090     CELER_EXPECT(this->has_exclusion() && i < this->size());
0091     return {inner_[i], inner_[i + 1]};
0092 }
0093 
0094 //---------------------------------------------------------------------------//
0095 /*!
0096  * Access lo/hi outer radii for a segment.
0097  */
0098 auto PolySegments::outer(size_type i) const -> Real2
0099 {
0100     CELER_EXPECT(i < this->size());
0101     return {outer_[i], outer_[i + 1]};
0102 }
0103 
0104 //---------------------------------------------------------------------------//
0105 /*!
0106  * Access lo/hi z values for a segment.
0107  */
0108 auto PolySegments::z(size_type i) const -> Real2
0109 {
0110     CELER_EXPECT(i < this->size());
0111     return {z_[i], z_[i + 1]};
0112 }
0113 
0114 //---------------------------------------------------------------------------//
0115 /*!
0116  * A segmented stack of same-type shapes with an azimuthal truncation.
0117  */
0118 class PolySolidBase : public ObjectInterface
0119 {
0120   public:
0121     // Anchored default virtual destructor
0122     ~PolySolidBase() override;
0123 
0124     //! Get the user-provided label
0125     std::string_view label() const final { return label_; }
0126 
0127     //! Axial segments
0128     PolySegments const& segments() const { return segments_; }
0129 
0130     //! Optional azimuthal angular restriction
0131     SolidEnclosedAngle enclosed_angle() const { return enclosed_; }
0132 
0133   protected:
0134     PolySolidBase(std::string&& label,
0135                   PolySegments&& segments,
0136                   SolidEnclosedAngle&& enclosed);
0137 
0138     //!@{
0139     //! Allow construction and assignment only through daughter classes
0140     CELER_DEFAULT_COPY_MOVE(PolySolidBase);
0141     //!@}
0142 
0143   private:
0144     std::string label_;
0145     PolySegments segments_;
0146     SolidEnclosedAngle enclosed_;
0147 };
0148 
0149 //---------------------------------------------------------------------------//
0150 /*!
0151  * A series of stacked cones or cylinders or combination of both.
0152  */
0153 class PolyCone final : public PolySolidBase
0154 {
0155   public:
0156     // Return a polycone *or* a simplified version for only a single segment
0157     static SPConstObject or_solid(std::string&& label,
0158                                   PolySegments&& segments,
0159                                   SolidEnclosedAngle&& enclosed);
0160 
0161     // Build with label, axial segments, optional restriction
0162     PolyCone(std::string&& label,
0163              PolySegments&& segments,
0164              SolidEnclosedAngle&& enclosed);
0165 
0166     // Construct a volume from this object
0167     NodeId build(VolumeBuilder&) const final;
0168 
0169     // Write the shape to JSON
0170     void output(JsonPimpl*) const final;
0171 };
0172 
0173 //---------------------------------------------------------------------------//
0174 /*!
0175  * A series of stacked regular prisms or cone-y prisms.
0176  */
0177 class PolyPrism final : public PolySolidBase
0178 {
0179   public:
0180     // Return a polyprism *or* a simplified version for only a single segment
0181     static SPConstObject or_solid(std::string&& label,
0182                                   PolySegments&& segments,
0183                                   SolidEnclosedAngle&& enclosed,
0184                                   int num_sides,
0185                                   real_type orientation);
0186 
0187     // Build with label, axial segments, parameters, optional restriction
0188     PolyPrism(std::string&& label,
0189               PolySegments&& segments,
0190               SolidEnclosedAngle&& enclosed,
0191               int num_sides,
0192               real_type orientation);
0193 
0194     // Construct a volume from this object
0195     NodeId build(VolumeBuilder&) const final;
0196 
0197     // Write the shape to JSON
0198     void output(JsonPimpl*) const final;
0199 
0200     //// ACCESSORS ////
0201 
0202     //! Number of sides
0203     int num_sides() const { return num_sides_; }
0204     //! Rotation factor
0205     real_type orientation() const { return orientation_; }
0206 
0207   private:
0208     int num_sides_;
0209     real_type orientation_;
0210 };
0211 
0212 //---------------------------------------------------------------------------//
0213 }  // namespace orangeinp
0214 }  // namespace celeritas