|
|
|||
File indexing completed on 2026-10-29 09:13:54
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 geocel/VolumePathAccumulator.hh 0006 //! \sa test/geocel/Volume.test.cc 0007 //---------------------------------------------------------------------------// 0008 #pragma once 0009 0010 #include "corecel/Assert.hh" 0011 #include "corecel/Macros.hh" 0012 0013 #include "VolumeData.hh" 0014 0015 namespace celeritas 0016 { 0017 //---------------------------------------------------------------------------// 0018 /*! 0019 * Incrementally compute the unique ID of a path in the volume hierarchy. 0020 * 0021 * Each \c VolumeUniqueInstanceId uniquely identifies a root-to-node path 0022 * (i.e., a Geant4 "touchable") in the volume DAG. This class computes the ID 0023 * on the fly without allocating a path buffer: call \c operator() once for 0024 * each \c VolumeInstanceId encountered while descending from the world volume, 0025 * passing the current accumulated ID and receiving the updated one. 0026 * 0027 * For a volume instance \c vi at position \c k in its 0028 * parent volume's children list, the offset is the sum of 0029 * \c num_desc(volume(vj)) for all preceding siblings \c vj (positions 0030 * 0..k-1), where \c num_desc(V) counts the total number of unique paths 0031 * ending at any node in V's subtree (including V itself). 0032 * For a path \f$[vi_0, vi_1, \ldots, vi_k]\f$ the unique instance ID is 0033 * \f[ 0034 * \text{uid} = \sum_{i=0}^{k} \bigl(\text{offset}[vi_i] + 1\bigr). 0035 * \f] 0036 * The empty path (the world volume itself, with no enclosing instance) maps 0037 * to ID 0 (see \c world_unique_instance ). 0038 * 0039 * \par Example: 0040 * \code 0041 VolumePathAccumulator accum{params.host_ref()}; 0042 VolumeUniqueInstanceId uid = world_unique_instance; 0043 for (VolumeInstanceId vi : path_below_world) 0044 { 0045 uid = accum(uid, vi); // unique ID for the node reached via this step 0046 } 0047 * \endcode 0048 * 0049 * or, if it's easier to include the world as part of the path (using unsigned 0050 * integer overflow that's part of the OpaqueId implementation), or if the path 0051 * might be "empty" to indicate being outside: 0052 * \code 0053 VolumePathAccumulator accum{params.host_ref()}; 0054 VolumeUniqueInstanceId uid; 0055 for (VolumeInstanceId vi : path_including_world) 0056 { 0057 uid = accum(uid, vi); // unique ID for the node reached via this step 0058 } 0059 * \endcode 0060 0061 * 0062 * \internal The mapping relies on \c unique_instance_offsets precomputed in 0063 * \c VolumeParamsData. 0064 */ 0065 class VolumePathAccumulator 0066 { 0067 public: 0068 //!@{ 0069 //! \name Type aliases 0070 using ParamsRef = NativeCRef<VolumeParamsData>; 0071 //!@} 0072 0073 public: 0074 //! Construct from volume hierarchy data 0075 explicit CELER_FUNCTION VolumePathAccumulator(ParamsRef const& params) 0076 : params_(params) 0077 { 0078 } 0079 0080 // Descend one level: add offset[vi]+1 to uid and return the result 0081 inline CELER_FUNCTION VolumeUniqueInstanceId operator()( 0082 VolumeUniqueInstanceId uid, VolumeInstanceId vi) const; 0083 0084 private: 0085 ParamsRef const& params_; 0086 }; 0087 0088 //---------------------------------------------------------------------------// 0089 // INLINE DEFINITIONS 0090 //---------------------------------------------------------------------------// 0091 /*! 0092 * Accumulate the contribution of one path step and return the updated ID. 0093 * 0094 * The result after \f$k\f$ calls equals the \c VolumeUniqueInstanceId of the 0095 * node reached via the first \f$k\f$ instances in the path. 0096 */ 0097 CELER_FUNCTION VolumeUniqueInstanceId VolumePathAccumulator::operator()( 0098 VolumeUniqueInstanceId uid, VolumeInstanceId vi) const 0099 { 0100 CELER_EXPECT(vi < params_.unique_instance_offsets.size()); 0101 auto const offset = params_.unique_instance_offsets[vi]; 0102 return VolumeUniqueInstanceId(*uid + offset.get() + 1); 0103 } 0104 0105 //---------------------------------------------------------------------------// 0106 } // namespace celeritas
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|