Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-31 09:38:42

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 /*!
0006  * \file orange/OrangeInput.hh
0007  * \brief Input data structures for an ORANGE geometry.
0008  *
0009  * \todo This is a weird mix of input and built objects so we can't put it in
0010  * \c inp . See discussion at
0011  * https://github.com/celeritas-project/celeritas/pull/2045#discussion_r2437457681
0012  */
0013 //---------------------------------------------------------------------------//
0014 #pragma once
0015 
0016 #include <algorithm>
0017 #include <iosfwd>
0018 #include <map>
0019 #include <variant>
0020 #include <vector>
0021 
0022 #include "corecel/io/Label.hh"
0023 #include "geocel/BoundingBox.hh"
0024 
0025 #include "OrangeData.hh"
0026 #include "OrangeTypes.hh"
0027 #include "inp/Bvh.hh"
0028 #include "surf/VariantSurface.hh"
0029 #include "transform/VariantTransform.hh"
0030 
0031 namespace celeritas
0032 {
0033 //---------------------------------------------------------------------------//
0034 /*!
0035  * Input definition for a single oriented bounding zone.
0036  */
0037 struct OrientedBoundingZoneInput
0038 {
0039     //! Inner bounding box
0040     BBox inner;
0041     //! Outer bounding box
0042     BBox outer;
0043     //! Local to global transformation
0044     TransformId trans_id;
0045 
0046     //! Whether the obz definition is valid
0047     explicit operator bool() const { return inner && outer && trans_id; }
0048 };
0049 
0050 //---------------------------------------------------------------------------//
0051 /*!
0052  * Input definition for a single ORANGE implementation volume.
0053  */
0054 struct VolumeInput
0055 {
0056     using Flags = LocalVolumeRecord::Flags;
0057     using VariantLabel = std::variant<Label, VolumeInstanceId>;
0058 
0059     //! Volume label or instance ID
0060     VariantLabel label{};
0061 
0062     //! Sorted list of surface IDs in this volume
0063     std::vector<LocalSurfaceId> faces{};
0064     //! RPN region definition for this volume, using local surface index
0065     std::vector<logic_int> logic{};
0066     //! Axis-aligned bounding box
0067     BBox bbox{};
0068     //! OrientedBoundingZone
0069     OrientedBoundingZoneInput obz;
0070 
0071     //! Special flags
0072     logic_int flags{0};
0073     //! Masking priority
0074     ZOrder zorder{};
0075 
0076     //! Whether the input definition is valid
0077     explicit operator bool() const
0078     {
0079         return (!logic.empty() || (flags & Flags::implicit_vol))
0080                && zorder != ZOrder::invalid;
0081     }
0082 };
0083 
0084 //---------------------------------------------------------------------------//
0085 /*!
0086  * Input definition a daughter universe embedded in a parent volume.
0087  */
0088 struct DaughterInput
0089 {
0090     UnivId univ_id;
0091     VariantTransform transform;
0092 };
0093 
0094 //---------------------------------------------------------------------------//
0095 /*!
0096  * Extra metadata for a unit's "background" volume.
0097  *
0098  * Unlike a regular volume, the "background" represents a \em volume rather
0099  * than a volume \em instance. Note that this can be an \em explicit volume
0100  * (i.e., made of booleans) or \em implicit (i.e., have the lowest "Z order").
0101  *
0102  * This is something of a hack: the background volume in a \c
0103  * orangeinp::UnitProto is annotated by setting the label to \c
0104  * VolumeInstanceId{} in \c g4org::ProtoConstructor; then converted from a
0105  * proto to a \c UnitInput by the \c InputBuilder, and finally in \c
0106  * g4org::Converter the empty volume instance IDs are replaced by (1) the
0107  * world \c VolumeInstanceId for the top-level background volume, or (2) the
0108  * \c VolumeId corresponding to the unit's label.
0109  */
0110 struct BackgroundInput
0111 {
0112     VolumeId label;
0113     LocalVolumeId volume;
0114 
0115     //! Whether the background metadata is used
0116     explicit operator bool() const { return static_cast<bool>(volume); }
0117 };
0118 
0119 //---------------------------------------------------------------------------//
0120 /*!
0121  * Input definition for a unit.
0122  *
0123  * \todo Add a CsgTree object and \c vector<NodeId> volumes;
0124  */
0125 struct UnitInput
0126 {
0127     using MapVolumeDaughter = std::map<LocalVolumeId, DaughterInput>;
0128     using MapLocalParent = std::map<LocalVolumeId, LocalVolumeId>;
0129 
0130     std::vector<VariantSurface> surfaces;
0131     std::vector<VolumeInput> volumes;
0132     //! Outer bounding box
0133     BBox bbox;
0134 
0135     //! The given local volume is replaced by a transformed universe
0136     MapVolumeDaughter daughter_map;
0137     //! The given local volume is structurally "inside" another local volume
0138     MapLocalParent local_parent_map;
0139     //! Metadata for the volume that represents the boundary of the unit
0140     BackgroundInput background;
0141 
0142     // Unit metadata
0143     std::vector<Label> surface_labels;
0144     Label label;
0145 
0146     //! Whether the unit definition is valid
0147     explicit operator bool() const { return !volumes.empty(); }
0148 };
0149 
0150 //---------------------------------------------------------------------------//
0151 /*!
0152  * Input definition for a rectangular array universe.
0153  */
0154 struct RectArrayInput
0155 {
0156     // Grid boundaries in x, y, and z
0157     Array<std::vector<double>, 3> grid;
0158 
0159     // Daughters in each volume [x][y][z]
0160     std::vector<DaughterInput> daughters;
0161 
0162     // Unit metadata
0163     Label label;
0164 
0165     //! Whether the universe definition is valid
0166     explicit operator bool() const
0167     {
0168         return !daughters.empty()
0169                && std::all_of(grid.begin(), grid.end(), [](auto& v) {
0170                       return v.size() >= 2;
0171                   });
0172     }
0173 };
0174 
0175 //---------------------------------------------------------------------------//
0176 /*!
0177  * Options that govern the geometry construction process.
0178  */
0179 struct ConstructionOptions
0180 {
0181     //! Options for Bounding Volume Hierarchy (BVH) construction
0182     inp::BvhBuilder bvh_options;
0183 
0184     //! Whether the options are valid
0185     explicit operator bool() const { return static_cast<bool>(bvh_options); }
0186 };
0187 
0188 //---------------------------------------------------------------------------//
0189 //! Possible types of universe inputs
0190 using VariantUniverseInput = std::variant<UnitInput, RectArrayInput>;
0191 
0192 //---------------------------------------------------------------------------//
0193 /*!
0194  * Construction definition for a full ORANGE geometry.
0195  *
0196  * The tolerance \c tol should be the same as at construction time: it will
0197  * be used at runtime to bump tracks if needed.
0198  *
0199  * The \c logic is used to convert to the runtime tracking implementation.
0200  * If set to \c LogicNotation::infix, the input logic \em must be simplified
0201  * to remove negation of parenthesized elements.
0202  */
0203 struct OrangeInput
0204 {
0205     std::vector<VariantUniverseInput> universes;
0206 
0207     ConstructionOptions construction_opts;
0208 
0209     //! Relative and absolute error for construction and transport
0210     Tolerance<> tol;
0211 
0212     //! Logic expression notation
0213     LogicNotation logic{LogicNotation::postfix};
0214 
0215     //! Whether the unit definition is valid
0216     explicit operator bool() const
0217     {
0218         return !universes.empty() && tol && logic != LogicNotation::size_
0219                && static_cast<bool>(construction_opts);
0220     }
0221 };
0222 
0223 //---------------------------------------------------------------------------//
0224 // Helper to read the input from a file or stream
0225 std::istream& operator>>(std::istream& is, OrangeInput&);
0226 
0227 //---------------------------------------------------------------------------//
0228 // Helper to write the input to a file or stream
0229 std::ostream& operator<<(std::ostream& os, OrangeInput const&);
0230 
0231 //---------------------------------------------------------------------------//
0232 }  // namespace celeritas