Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 09:06:16

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 orange/SenseUtils.hh
0006 //! \brief Sense helper functions and types.
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include "corecel/Macros.hh"
0011 #include "corecel/cont/Bitset.hh"
0012 
0013 #include "OrangeTypes.hh"
0014 
0015 namespace celeritas
0016 {
0017 //---------------------------------------------------------------------------//
0018 // HELPER FUNCTIONS (HOST/DEVICE)
0019 //---------------------------------------------------------------------------//
0020 /*!
0021  * Convert a boolean value to a Sense enum.
0022  */
0023 CELER_CONSTEXPR_FUNCTION Sense to_sense(bool s)
0024 {
0025     return static_cast<Sense>(s);
0026 }
0027 
0028 //---------------------------------------------------------------------------//
0029 /*!
0030  * Change the sense across a surface.
0031  */
0032 [[nodiscard]] CELER_CONSTEXPR_FUNCTION Sense flip_sense(Sense orig)
0033 {
0034     return static_cast<Sense>(!static_cast<bool>(orig));
0035 }
0036 
0037 //---------------------------------------------------------------------------//
0038 /*!
0039  * Change the sense across a surface.
0040  */
0041 [[nodiscard]] CELER_CONSTEXPR_FUNCTION SignedSense flip_sense(SignedSense orig)
0042 {
0043     using IntT = std::underlying_type_t<SignedSense>;
0044     return static_cast<SignedSense>(-static_cast<IntT>(orig));
0045 }
0046 
0047 //---------------------------------------------------------------------------//
0048 /*!
0049  * Evaluate the sense based on the LHS expression of the quadric equation.
0050  *
0051  * This is an optimized jump-free version of:
0052  * \code
0053     return quadric == 0 ? SignedSense::on
0054         : quadric < 0 ? SignedSense::inside
0055         : SignedSense::outside;
0056  * \endcode
0057  * as
0058  * \code
0059     int gz = !(quadric <= 0) ? 1 : 0;
0060     int lz = quadric < 0 ? 1 : 0;
0061     return static_cast<SignedSense>(gz - lz);
0062  * \endcode
0063  * and compressed into a single line.
0064  *
0065  * NaN values are treated as "outside".
0066  */
0067 [[nodiscard]] CELER_CONSTEXPR_FUNCTION SignedSense
0068 real_to_sense(real_type quadric)
0069 {
0070     return static_cast<SignedSense>(!(quadric <= 0) - (quadric < 0));
0071 }
0072 
0073 //---------------------------------------------------------------------------//
0074 /*!
0075  * Convert a signed sense to a Sense enum.
0076  */
0077 CELER_CONSTEXPR_FUNCTION Sense to_sense(SignedSense s)
0078 {
0079     return Sense(static_cast<int>(s) >= 0);
0080 }
0081 
0082 //---------------------------------------------------------------------------//
0083 /*!
0084  * Convert a signed sense to a surface state.
0085  */
0086 CELER_CONSTEXPR_FUNCTION SurfaceState to_surface_state(SignedSense s)
0087 {
0088     return s == SignedSense::on ? SurfaceState::on : SurfaceState::off;
0089 }
0090 
0091 //---------------------------------------------------------------------------//
0092 // HELPER FUNCTIONS (HOST)
0093 //---------------------------------------------------------------------------//
0094 //! Get a printable character corresponding to a sense.
0095 inline constexpr char to_char(Sense s)
0096 {
0097     return s == Sense::inside ? '-' : '+';
0098 }
0099 
0100 // Get a string corresponding to a signed sense
0101 inline char const* to_cstring(SignedSense s)
0102 {
0103     switch (s)
0104     {
0105         case SignedSense::inside:
0106             return "inside";
0107         case SignedSense::on:
0108             return "on";
0109         case SignedSense::outside:
0110             return "outside";
0111     }
0112     return "<invalid>";
0113 }
0114 
0115 //---------------------------------------------------------------------------//
0116 // CLASSES
0117 //---------------------------------------------------------------------------//
0118 /*!
0119  * Wrapper for a sense value that is optionally set.
0120  */
0121 class SenseValue
0122 {
0123   private:
0124     enum : char
0125     {
0126         sense_bit,
0127         is_assigned_bit,
0128     };
0129 
0130   public:
0131     constexpr SenseValue() = default;
0132 
0133     //! Construct with a sense value
0134     CELER_CONSTEXPR_FUNCTION SenseValue(Sense sense)
0135     {
0136         sense_[sense_bit] = static_cast<bool>(sense);
0137         sense_[is_assigned_bit] = true;
0138     }
0139 
0140     //! Convert to a sense value
0141     CELER_CONSTEXPR_FUNCTION operator Sense() const
0142     {
0143         return to_sense(sense_[sense_bit]);
0144     }
0145 
0146     //! Convert to a boolean value
0147     CELER_CONSTEXPR_FUNCTION explicit operator bool() const
0148     {
0149         return sense_[sense_bit];
0150     }
0151 
0152     //! Assign a sense value
0153     CELER_CONSTEXPR_FUNCTION SenseValue& operator=(Sense sense)
0154     {
0155         sense_[sense_bit] = static_cast<bool>(sense);
0156         sense_[is_assigned_bit] = true;
0157         return *this;
0158     }
0159 
0160     //! Check wether there is a cached sense value
0161     CELER_CONSTEXPR_FUNCTION bool is_assigned() const
0162     {
0163         return sense_[is_assigned_bit];
0164     }
0165 
0166     //! Clear the sense value
0167     CELER_CONSTEXPR_FUNCTION void clear() { sense_.reset(); }
0168 
0169   private:
0170     Bitset<2> sense_;
0171 };
0172 
0173 }  // namespace celeritas