Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-13 08:53:31

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 celeritas/grid/GridIdFinder.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Assert.hh"
0010 #include "corecel/Macros.hh"
0011 #include "corecel/cont/Span.hh"
0012 #include "corecel/data/LdgIterator.hh"
0013 #include "corecel/math/Algorithms.hh"
0014 
0015 namespace celeritas
0016 {
0017 //---------------------------------------------------------------------------//
0018 /*!
0019  * Map an input grid to an ID type, returning invalid ID if outside bounds.
0020  *
0021  * The input grid should be a monotonic increasing series, and the
0022  * corresponding ID values should be one fewer (cell-centered data). Values
0023  * outside the grid bounds are unassigned, and grid points are attached to the
0024  * model ID above the corresponding value.
0025  *
0026  * \code
0027     GridIdFinder<MevEnergy, ActionId> find_model(energy, values);
0028 
0029     ActionId applicable_model = find_model(particle.energy());
0030    \endcode
0031  */
0032 template<class KeyQuantity, class ValueId>
0033 class GridIdFinder
0034 {
0035     static_assert(KeyQuantity::unit_type::value() > 0, "Invalid Quantity");
0036     static_assert(sizeof(typename ValueId::size_type), "Invalid OpaqueId");
0037 
0038   public:
0039     //!@{
0040     //! \name Type aliases
0041     using argument_type = KeyQuantity;
0042     using result_type = ValueId;
0043 
0044     using SpanConstGrid = LdgSpan<typename KeyQuantity::value_type const>;
0045     using SpanConstValue = LdgSpan<result_type const>;
0046     //!@}
0047 
0048   public:
0049     // Construct from grid and values.
0050     inline CELER_FUNCTION GridIdFinder(SpanConstGrid, SpanConstValue);
0051 
0052     // Find the given grid point
0053     inline CELER_FUNCTION result_type operator()(argument_type arg) const;
0054 
0055   private:
0056     SpanConstGrid grid_;
0057     SpanConstValue value_;
0058 };
0059 
0060 //---------------------------------------------------------------------------//
0061 // INLINE DEFINITIONS
0062 //---------------------------------------------------------------------------//
0063 /*!
0064  * Construct from grid and values.
0065  *
0066  * \todo Construct from reference to collections and ranges so we can benefit
0067  * from
0068  * __ldg as needed
0069  */
0070 template<class K, class V>
0071 CELER_FUNCTION
0072 GridIdFinder<K, V>::GridIdFinder(SpanConstGrid grid, SpanConstValue value)
0073     : grid_(grid), value_(value)
0074 {
0075     CELER_EXPECT(grid_.size() == value_.size() + 1);
0076 }
0077 
0078 //---------------------------------------------------------------------------//
0079 /*!
0080  * Find the ID corresponding to the given value.
0081  */
0082 template<class K, class V>
0083 CELER_FUNCTION auto
0084 GridIdFinder<K, V>::operator()(argument_type quant) const -> result_type
0085 {
0086     auto iter
0087         = celeritas::lower_bound(grid_.begin(), grid_.end(), quant.value());
0088     if (iter == grid_.end()
0089         || (iter == grid_.begin() && quant.value() != *iter))
0090     {
0091         // Higher than end point or below first point
0092         return {};
0093     }
0094     else if (iter + 1 == grid_.end() || quant.value() != *iter)
0095     {
0096         // Exactly on end grid point, or not on a grid point at all: move to
0097         // previous bin
0098         --iter;
0099     }
0100     return value_[iter - grid_.begin()];
0101 }
0102 
0103 //---------------------------------------------------------------------------//
0104 }  // namespace celeritas