Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-18 09:18:19

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/UnitProto.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <string>
0010 #include <vector>
0011 
0012 #include "geocel/Types.hh"
0013 #include "orange/OrangeTypes.hh"
0014 #include "orange/transform/VariantTransform.hh"
0015 
0016 #include "CsgTypes.hh"
0017 #include "ProtoInterface.hh"
0018 
0019 namespace celeritas
0020 {
0021 namespace orangeinp
0022 {
0023 class Transformed;
0024 
0025 namespace detail
0026 {
0027 struct CsgUnit;
0028 }  // namespace detail
0029 
0030 //---------------------------------------------------------------------------//
0031 /*!
0032  * Construct a general CSG universe, aka a "unit".
0033  *
0034  * A "unit" is a region of space (specified by the "boundary" object) that is
0035  * divided up into multiple smaller regions:
0036  * - A "material" (aka "media" in SCALE) is a single homogeneous CSG object
0037  *   filled with a particular material ID. This is equivalent to a leaf
0038  *   "physical volume" in a GDML/Geant4 volume hierarchy.
0039  * - A "daughter" (aka "hole" in SCALE) is another unit that is transformed and
0040  *   placed into this universe.
0041  *
0042  * Regarding boundary conditions: "Input" is for how the unit is *defined*:
0043  *
0044  *  ========== ==========================================================
0045  *   Input      Description
0046  *  ========== ==========================================================
0047  *   Implicit   Boundary implicitly truncates interior (KENO)
0048  *   Explicit   Interior CSG definition includes boundary (RTK)
0049  *  ========== ==========================================================
0050  *
0051  * Additionally, whether the universe is the top-level \em global universe (see
0052  * the \c ExteriorBoundary type) affects the construction.
0053  *
0054  *  ========== ==========================================================
0055  *   ExtBound   Description
0056  *  ========== ==========================================================
0057  *   Daughter   Boundary is already truncated by higher-level unit
0058  *   Global     Boundary must explicitly be represented as a volume
0059  *  ========== ==========================================================
0060  *
0061  * These result in different z ordering for the exterior:
0062  *
0063  *  ===== ===== ================== ========================================
0064  *   Inp   ExB   Resulting zorder   Description
0065  *  ===== ===== ================== ========================================
0066  *   I     N     implicit_exterior  Higher-level universe truncates
0067  *   X     N     implicit_exterior  Higher-level universe truncates
0068  *   I     Y     exterior           Global unit that truncates other regions
0069  *   X     Y     media              Global unit with well-connected exterior
0070  *  ===== ===== ================== ========================================
0071  */
0072 class UnitProto : public ProtoInterface
0073 {
0074   public:
0075     //!@{
0076     //! \name Types
0077     using Unit = detail::CsgUnit;
0078     using Tol = Tolerance<>;
0079 
0080     //! Optional "background" inside of exterior, outside of all mat/daughter
0081     struct BackgroundInput
0082     {
0083         GeoMatId fill{};
0084         Label label;
0085 
0086         // True if fill or label is specified
0087         explicit inline operator bool() const;
0088     };
0089 
0090     //! A homogeneous physical material
0091     struct MaterialInput
0092     {
0093         SPConstObject interior;
0094         GeoMatId fill;
0095         Label label;
0096 
0097         // True if fully defined
0098         explicit inline operator bool() const;
0099     };
0100 
0101     //! Another universe embedded within this one
0102     struct DaughterInput
0103     {
0104         SPConstProto fill;  //!< Daughter unit
0105         VariantTransform transform;  //!< Daughter-to-parent
0106         ZOrder zorder{ZOrder::media};  //!< Overlap control
0107 
0108         // True if fully defined
0109         explicit inline operator bool() const;
0110 
0111         // Construct the daughter's shape in this unit's reference frame
0112         SPConstObject make_interior() const;
0113     };
0114 
0115     //! Boundary conditions for the unit
0116     struct BoundaryInput
0117     {
0118         SPConstObject interior;  //!< Bounding shape for the unit
0119         ZOrder zorder{ZOrder::exterior};  //!< Overlap control
0120 
0121         // True if fully defined
0122         explicit inline operator bool() const;
0123     };
0124 
0125     //! Required input data to create a unit proto
0126     struct Input
0127     {
0128         BackgroundInput background;
0129         std::vector<MaterialInput> materials;
0130         std::vector<DaughterInput> daughters;
0131         BoundaryInput boundary;
0132         std::string label;
0133         UnitSimplification simplification{UnitSimplification::none};
0134 
0135         // True if fully defined
0136         explicit inline operator bool() const;
0137     };
0138     //!@}
0139 
0140   public:
0141     // Construct with required input data
0142     explicit UnitProto(Input&& inp);
0143 
0144     virtual ~UnitProto() = default;
0145 
0146     // Short unique name of this object
0147     std::string_view label() const final;
0148 
0149     // Get the boundary of this universe as an object
0150     SPConstObject interior() const final;
0151 
0152     // Get a list of all daughters
0153     VecProto daughters() const final;
0154 
0155     // Construct a universe input from this object
0156     void build(ProtoBuilder&) const final;
0157 
0158     // Write the proto to a JSON object
0159     void output(JsonPimpl*) const final;
0160 
0161     //// HELPER FUNCTIONS ////
0162 
0163     // Construct a standalone unit for testing and external interface
0164     Unit build(Tol const& tol, BBox const& bbox) const;
0165 
0166   private:
0167     Input input_;
0168 };
0169 
0170 //---------------------------------------------------------------------------//
0171 /*!
0172  * True if either material or label is provided.
0173  */
0174 UnitProto::BackgroundInput::operator bool() const
0175 {
0176     return this->fill || !this->label.empty();
0177 }
0178 
0179 //---------------------------------------------------------------------------//
0180 /*!
0181  * True if fully defined.
0182  */
0183 UnitProto::MaterialInput::operator bool() const
0184 {
0185     return static_cast<bool>(this->interior);
0186 }
0187 
0188 //---------------------------------------------------------------------------//
0189 /*!
0190  * True if fully defined.
0191  */
0192 UnitProto::DaughterInput::operator bool() const
0193 {
0194     return static_cast<bool>(this->fill);
0195 }
0196 
0197 //---------------------------------------------------------------------------//
0198 /*!
0199  * True if fully defined.
0200  */
0201 UnitProto::BoundaryInput::operator bool() const
0202 {
0203     return static_cast<bool>(this->interior);
0204 }
0205 
0206 //---------------------------------------------------------------------------//
0207 /*!
0208  * True if fully defined.
0209  *
0210  * The unit proto must have at least one material, daughter, or background
0211  * fill.
0212  */
0213 UnitProto::Input::operator bool() const
0214 {
0215     return (!this->materials.empty() || !this->daughters.empty()
0216             || this->background)
0217            && this->boundary;
0218 }
0219 
0220 //---------------------------------------------------------------------------//
0221 }  // namespace orangeinp
0222 }  // namespace celeritas