Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:17:11

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