Back to home page

EIC code displayed by LXR

 
 

    


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/UnitProto.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include <string>
0011 #include <vector>
0012 
0013 #include "geocel/Types.hh"
0014 #include "orange/OrangeTypes.hh"
0015 #include "orange/transform/VariantTransform.hh"
0016 
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         GeoMaterialId 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         GeoMaterialId 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 
0134         // True if fully defined
0135         explicit inline operator bool() const;
0136     };
0137     //!@}
0138 
0139   public:
0140     // Construct with required input data
0141     explicit UnitProto(Input&& inp);
0142 
0143     // Short unique name of this object
0144     std::string_view label() const final;
0145 
0146     // Get the boundary of this universe as an object
0147     SPConstObject interior() const final;
0148 
0149     // Get a list of all daughters
0150     VecProto daughters() const final;
0151 
0152     // Construct a universe input from this object
0153     void build(ProtoBuilder&) const final;
0154 
0155     // Write the proto to a JSON object
0156     void output(JsonPimpl*) const final;
0157 
0158     //// HELPER FUNCTIONS ////
0159 
0160     // Construct a standalone unit for testing and external interface
0161     Unit build(Tol const& tol, BBox const& bbox) const;
0162 
0163   private:
0164     Input input_;
0165 };
0166 
0167 //---------------------------------------------------------------------------//
0168 /*!
0169  * True if either material or label is provided.
0170  */
0171 UnitProto::BackgroundInput::operator bool() const
0172 {
0173     return this->fill || !this->label.empty();
0174 }
0175 
0176 //---------------------------------------------------------------------------//
0177 /*!
0178  * True if fully defined.
0179  */
0180 UnitProto::MaterialInput::operator bool() const
0181 {
0182     return static_cast<bool>(this->interior);
0183 }
0184 
0185 //---------------------------------------------------------------------------//
0186 /*!
0187  * True if fully defined.
0188  */
0189 UnitProto::DaughterInput::operator bool() const
0190 {
0191     return static_cast<bool>(this->fill);
0192 }
0193 
0194 //---------------------------------------------------------------------------//
0195 /*!
0196  * True if fully defined.
0197  */
0198 UnitProto::BoundaryInput::operator bool() const
0199 {
0200     return static_cast<bool>(this->interior);
0201 }
0202 
0203 //---------------------------------------------------------------------------//
0204 /*!
0205  * True if fully defined.
0206  *
0207  * The unit proto must have at least one material, daughter, or background
0208  * fill.
0209  */
0210 UnitProto::Input::operator bool() const
0211 {
0212     return (!this->materials.empty() || !this->daughters.empty()
0213             || this->background)
0214            && this->boundary;
0215 }
0216 
0217 //---------------------------------------------------------------------------//
0218 }  // namespace orangeinp
0219 }  // namespace celeritas