Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-26 09:34:36

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 corecel/math/ArrayQuantity.hh
0006 //! \brief Create and convert arrays of quantities
0007 //! \sa corecel/math/Quantity.test.cc
0008 //---------------------------------------------------------------------------//
0009 #pragma once
0010 
0011 #include <cstddef>
0012 #include <type_traits>
0013 
0014 #include "corecel/Types.hh"
0015 #include "corecel/cont/Array.hh"
0016 
0017 #include "Quantity.hh"
0018 
0019 #if !CELER_DEVICE_COMPILE
0020 #    include <ostream>
0021 #endif
0022 
0023 namespace celeritas
0024 {
0025 
0026 //---------------------------------------------------------------------------//
0027 /*!
0028  * Construct an array of quantities from raw values.
0029  *
0030  * This helper function allows concise construction of arrays of quantities:
0031  * \code
0032  * auto distances = make_quantity_array<CmLength>(1.0, 2.5, 3.7);
0033  * \endcode
0034  */
0035 template<class Q, class... Args>
0036 CELER_CONSTEXPR_FUNCTION Array<Q, sizeof...(Args)> make_quantity_array(
0037     Args const&... args) noexcept
0038 {
0039     static_assert(is_quantity_v<Q>);
0040     return {Q{args}...};
0041 }
0042 
0043 //! \cond (CELERITAS_DOC_DEV)
0044 //---------------------------------------------------------------------------//
0045 /*!
0046  * Construct an array of quantities from raw values.
0047  *
0048  * This helper function allows concise construction of arrays of quantities:
0049  * \code
0050  * auto pos = make_quantity_array<CmLength>(hardcoded_pos_cm);
0051  * \endcode
0052  */
0053 template<class Q, std::size_t N>
0054 CELER_CONSTEXPR_FUNCTION Array<Q, N> make_quantity_array(
0055     Array<typename Q::value_type, N> const& arr) noexcept
0056 {
0057     static_assert(is_quantity_v<Q>);
0058     Array<Q, N> result;
0059     for (std::size_t i = 0; i < N; ++i)
0060     {
0061         result[i] = Q{arr[i]};
0062     }
0063     return result;
0064 }
0065 
0066 //---------------------------------------------------------------------------//
0067 /*!
0068  * Convert an array of quantities to native values.
0069  *
0070  * This applies native_value_from element-wise to each component.
0071  */
0072 template<class UnitT, class ValueT, std::size_t N>
0073 CELER_CONSTEXPR_FUNCTION auto native_value_from(
0074     Array<Quantity<UnitT, ValueT>, N> const& quant) noexcept
0075 {
0076     using common_type = typename Quantity<UnitT, ValueT>::common_type;
0077     Array<common_type, N> result;
0078     for (std::size_t i = 0; i < N; ++i)
0079     {
0080         result[i] = native_value_from(quant[i]);
0081     }
0082     return result;
0083 }
0084 
0085 //---------------------------------------------------------------------------//
0086 /*!
0087  * Convert an array of native values to an array of quantities.
0088  *
0089  * This applies native_value_to element-wise to each component.
0090  */
0091 template<class Q, class T, std::size_t N>
0092 CELER_CONSTEXPR_FUNCTION auto native_value_to(Array<T, N> const& value) noexcept
0093 {
0094     static_assert(is_quantity_v<Q>);
0095     Array<Q, N> result;
0096     for (std::size_t i = 0; i < N; ++i)
0097     {
0098         result[i] = native_value_to<Q>(value[i]);
0099     }
0100     return result;
0101 }
0102 
0103 //---------------------------------------------------------------------------//
0104 /*!
0105  * Get the values from an array of quantities.
0106  *
0107  * This applies value_as element-wise to each component.
0108  */
0109 template<class Q, std::size_t N>
0110 CELER_CONSTEXPR_FUNCTION auto value_as(Array<Q, N> const& quant) noexcept
0111     -> std::enable_if_t<is_quantity_v<Q>, Array<typename Q::value_type, N>>
0112 {
0113     Array<typename Q::value_type, N> result;
0114     for (std::size_t i = 0; i < N; ++i)
0115     {
0116         result[i] = value_as<Q>(quant[i]);
0117     }
0118     return result;
0119 }
0120 
0121 #if !CELER_DEVICE_COMPILE
0122 //---------------------------------------------------------------------------//
0123 /*!
0124  * Output a quantity array with its label.
0125  *
0126  * This overload is more specialized than the generic Array operator<< and is
0127  * therefore preferred by partial ordering for Quantity element types.
0128  */
0129 template<class UnitT, class ValueT, std::size_t N>
0130 std::ostream& operator<<(std::ostream& os,
0131                          Array<Quantity<UnitT, ValueT>, N> const& q)
0132 {
0133     os << value_as<Quantity<UnitT, ValueT>>(q) << " [" << UnitT::label() << ']';
0134     return os;
0135 }
0136 #endif
0137 
0138 //! \endcond
0139 //---------------------------------------------------------------------------//
0140 }  // namespace celeritas