Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-13 11:00:09

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright VecGeom contributors: see top-level LICENSE file for details
0003 // SPDX-License-Identifier: Apache-2.0
0004 //---------------------------------------------------------------------------//
0005 //! \file VecGeom/navigation/NavFindResult.h
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "VecGeom/base/Assert.h"
0010 #include "VecGeom/base/Macros.h"
0011 #include "VecGeom/base/Math.h"
0012 
0013 #if !VECGEOM_DEVICE_COMPILE
0014 #include <ostream>
0015 #endif
0016 
0017 namespace vecgeom {
0018 //---------------------------------------------------------------------------//
0019 
0020 /*!
0021  * Classification of a boundary search result.
0022  *
0023  * The \c NavFindResult uses this classification in conjunction with its
0024  * returned distance (see \c NavFindResult::GetDistance() ) and the expected
0025  * next actions of the \c NavView (see \c NavView::FindNextBoundary() ).
0026  *  - \c hit: an intersection with another volume has been found at a
0027  *    strictly positive distance.
0028  *  - \c miss: no boundary was found within the search distance
0029  *  - \c reentrant: an intersection was found at zero (or slightly negative)
0030  *    distance, indicating the search was performed on a boundary while headed
0031  *    outward from the current volume.
0032  *  - \c error: a nontrivial negative distance was encountered to the next
0033  *    volume, likely indicating a geometry overlap or navigation error.
0034  */
0035 enum class NavFindResultKind {
0036   hit,       //!< intersection found
0037   miss,      //!< no intersection found within specified search distance
0038   reentrant, //!< on a boundary headed into it: zero distance to cross
0039   error,     //!< overlap detected
0040   size_      // (enum size sentinel)
0041 };
0042 
0043 #if !VECGEOM_DEVICE_COMPILE
0044 //! Get a string representation of the result
0045 inline char const *ToString(NavFindResultKind k)
0046 {
0047   // TODO: use corecel::EnumToString
0048   constexpr auto size                   = static_cast<int>(NavFindResultKind::size_);
0049   static char const *const values[size] = {"hit", "miss", "reentrant", "error"};
0050   return values[static_cast<int>(k)];
0051 }
0052 
0053 //! Print the result for debugging and testing
0054 inline std::ostream &operator<<(std::ostream &os, NavFindResultKind k) { return (os << ToString(k)); }
0055 #endif
0056 
0057 /*!
0058  * Boundary search result.
0059  *
0060  * Returned by \c NavView::FindNextBoundary, this provides an unambiguous
0061  * interface to the combination of "next distance" and "boundary flag".
0062  * The distance is \em only meaningful if the result is a
0063  * \c NavFindResultKind::hit.
0064  */
0065 class NavFindResult {
0066 public:
0067   using Kind = NavFindResultKind;
0068   using Real = ::vecgeom::Precision;
0069 
0070   //! Create a find "missed" find result
0071   static constexpr VECGEOM_FUNCTION NavFindResult Miss() { return NavFindResult{Kind::miss}; }
0072 
0073   //! Create a find "reentrant" find result
0074   static constexpr VECGEOM_FUNCTION NavFindResult Reentrant() { return NavFindResult{Kind::reentrant}; }
0075 
0076   //! Create a find "error" find result
0077   static constexpr VECGEOM_FUNCTION NavFindResult Error() { return NavFindResult{Kind::error}; }
0078 
0079   //! Prohibit default construction
0080   constexpr VECGEOM_FUNCTION NavFindResult() = delete;
0081 
0082   //! Initialize with \em positive distance to hit
0083   explicit constexpr VECGEOM_FUNCTION NavFindResult(Real distance) : kind_{Kind::hit}, distance_{distance}
0084   {
0085     VECGEOM_ASSERT(distance_ > 0);
0086   }
0087 
0088   //! Get the category of search result: hit, miss, reentrant, error
0089   constexpr VECGEOM_FUNCTION Kind GetKind() const { return kind_; }
0090 
0091   //! Get the distance to a hit: can be called only when kind == hit
0092   constexpr VECGEOM_FUNCTION Real GetDistance() const
0093   {
0094     VECGEOM_ASSERT(kind_ == Kind::hit);
0095     return distance_;
0096   }
0097 
0098 #if !VECGEOM_DEVICE_COMPILE
0099   //! Print the result for debugging and testing
0100   friend std::ostream &operator<<(std::ostream &os, NavFindResult const &r)
0101   {
0102     os << r.GetKind();
0103     if (r.GetKind() == Kind::hit) {
0104       os << '@' << r.GetDistance();
0105     }
0106     return os;
0107   }
0108 #endif
0109 
0110 private:
0111   Kind kind_{};
0112   Real distance_{};
0113 
0114   //! Private constructor used by static helpers: initialize with a non-hit value
0115   explicit constexpr VECGEOM_FUNCTION NavFindResult(Kind k) : kind_{k} { VECGEOM_ASSERT(kind_ != Kind::hit); }
0116 };
0117 
0118 //---------------------------------------------------------------------------//
0119 } // namespace vecgeom