Back to home page

EIC code displayed by LXR

 
 

    


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/VolumeCollectionBuilder.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <type_traits>
0010 
0011 #include "corecel/Types.hh"
0012 #include "corecel/cont/Range.hh"
0013 #include "corecel/data/CollectionBuilder.hh"
0014 
0015 #include "Types.hh"
0016 
0017 namespace celeritas
0018 {
0019 class GeoParamsInterface;
0020 //---------------------------------------------------------------------------//
0021 /*!
0022  * Create a "collection" that maps from ImplVolumeId to a value.
0023  *
0024  * This builds collections for runtime execution using a GeoTrackView's \c
0025  * impl_volume_id() call, which requires less indirection than \c volume_id() .
0026  *
0027  * Given a geometry (which is allowed to be \c GeoParamsInterface ), a function
0028  * \code T(*)(VolumeId) \endcode will be called for every \c ImplVolumeId in
0029  * the geometry that corresponds to a canonical volume. The resulting value
0030  * will be assigned to the collection.
0031  */
0032 template<class T, class G, class F>
0033 inline Collection<T, Ownership::value, MemSpace::host, ImplVolumeId>
0034 build_volume_collection(G const& geo, F&& fill_value)
0035 {
0036     static_assert(std::is_base_of_v<GeoParamsInterface, G>,
0037                   "G must be a geometry class");
0038     static_assert(std::is_convertible_v<std::invoke_result_t<F, VolumeId>, T>,
0039                   "Incorrect return type for F");
0040 
0041     // Helper lambda to get the appropriate value
0042     auto fill_or_default = [&](ImplVolumeId iv_id) -> T {
0043         if (auto vol_id = geo.volume_id(iv_id))
0044         {
0045             return fill_value(vol_id);
0046         }
0047         return {};
0048     };
0049 
0050     // Create a collection sized for each implementation volume
0051     Collection<T, Ownership::value, MemSpace::host, ImplVolumeId> result;
0052     auto num_impl_volumes = geo.impl_volumes().size();
0053     resize(&result, num_impl_volumes);
0054 
0055     // Fill values
0056     for (auto iv_id : range(ImplVolumeId{num_impl_volumes}))
0057     {
0058         result[iv_id] = fill_or_default(iv_id);
0059     }
0060     return result;
0061 }
0062 
0063 //---------------------------------------------------------------------------//
0064 /*!
0065  * Helper class to fill a volume collection from a map.
0066  *
0067  * Example:
0068  * \code
0069    host_data.detector
0070        = build_volume_collection<DetectorId>(geo, VolumeMapFiller{det_ids});
0071  * \endcode
0072  */
0073 template<class T>
0074 class VolumeMapFiller
0075 {
0076     static_assert(std::is_same_v<typename T::key_type, VolumeId>,
0077                   "Not a map of volume to value");
0078 
0079   public:
0080     using mapped_type = typename T::mapped_type;
0081 
0082   public:
0083     //! Construct with map to use
0084     explicit VolumeMapFiller(T const& m) : from_vol_(m) {}
0085 
0086     //! Get the value from a volume ID or default if not in the map
0087     mapped_type operator()(VolumeId vol_id) const
0088     {
0089         if (auto iter = from_vol_.find(vol_id); iter != from_vol_.end())
0090         {
0091             return iter->second;
0092         }
0093         return {};
0094     }
0095 
0096   private:
0097     T const& from_vol_;
0098 };
0099 
0100 //---------------------------------------------------------------------------//
0101 }  // namespace celeritas