Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-29 09:13:53

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/CheckedGeoTrackView.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <memory>
0010 #include <optional>
0011 
0012 #include "corecel/Assert.hh"
0013 #include "corecel/io/Logger.hh"
0014 #include "geocel/GeoTrackInterface.hh"
0015 #include "geocel/Types.hh"
0016 #include "geocel/UnitLength.hh"
0017 
0018 namespace celeritas
0019 {
0020 //---------------------------------------------------------------------------//
0021 template<class RT>
0022 class GeoTrackInterface;
0023 class GeoParamsInterface;
0024 class VolumeParams;
0025 
0026 //---------------------------------------------------------------------------//
0027 /*!
0028  * Check validity of safety and volume crossings while navigating on CPU.
0029  *
0030  * This wraps a \c GeoTrackInterface and adds validation, instrumentation,
0031  * and logging.
0032  * - Validates input arguments and resulting state from the track view
0033  * - Counts the number of calls to \c find_next_step and \c find_safety
0034  * - Logs state changes at a debug level, and warns of unexpected conditions
0035  *
0036  * The constructor copies the "local" logger's target and level by default,
0037  * with the level overridden by the \c CELER_LOG_GEO env variable.
0038  * - \c warning prints minor inconsistencies/potential issues
0039  * - \c status also prints mutating actions and boundary/safety searches after
0040  *   they are completed
0041  * - \c debug also prints initialization and post-crossing state, as well as
0042  *   function trace (in case an error is thrown)
0043  *
0044  * Two flags can alter the error checking:
0045  * - \c check_normal will validate the normal calculation when on a boundary
0046  * - \c check_failure will throw before and after a call
0047  *
0048  * The only nontrivial function that can be called from an outside or failed
0049  * state is initialization (with \c operator= ).
0050  */
0051 class CheckedGeoTrackView final : public GeoTrackInterface<real_type>
0052 {
0053   public:
0054     //!@{
0055     //! \name Type aliases
0056     using Initializer_t = GeoTrackInitializer;
0057     using Real3 = Array<real_type, 3>;
0058     using TrackT = GeoTrackInterface<real_type>;
0059     using UPTrack = std::unique_ptr<TrackT>;
0060     using SPConstGeoI = std::shared_ptr<GeoParamsInterface const>;
0061     using SPConstVolumes = std::shared_ptr<VolumeParams const>;
0062     //!@}
0063 
0064   public:
0065     //! Construct with a unique pointer to a geo track view
0066     explicit CheckedGeoTrackView(UPTrack track)
0067         : CheckedGeoTrackView{std::move(track), nullptr, nullptr, UnitLength{}}
0068     {
0069     }
0070 
0071     // Construct with a unique pointer to a geo track view
0072     CheckedGeoTrackView(UPTrack track,
0073                         SPConstVolumes volumes,
0074                         SPConstGeoI geo_interface,
0075                         UnitLength unit_length);
0076 
0077     // Allow moving for customization
0078     CELER_DEFAULT_MOVE_DELETE_COPY(CheckedGeoTrackView);
0079 
0080     //! Check if we were "moved from" (permanently invalid state)
0081     explicit operator bool() const { return t_ != nullptr; }
0082 
0083     //! Access the underlying track view
0084     TrackT const& track_view() const { return *t_; }
0085     //! Access the underlying track view
0086     TrackT& track_view() { return *t_; }
0087 
0088     //! Access the underlying logger
0089     Logger const& logger() const { return log_; }
0090     //! Access the underlying logger
0091     Logger& logger() { return log_; }
0092 
0093     //! Check volume consistency this far from the boundary
0094     real_type safety_tol() const { return 1e-4 * unit_length_.value; }
0095 
0096     //// ACCESSORS ////
0097 
0098     //! Number of calls of find_next_step
0099     size_type intersect_count() const { return count_.intersect; }
0100     //! Number of calls of find_safety
0101     size_type safety_count() const { return count_.safety; }
0102     //! Reset the counters
0103     void reset_count() { count_ = {}; }
0104 
0105     //! Enable/disable normal checking
0106     void check_normal(bool value) { check_normal_ = value; }
0107     //! Whether normal checking is enabled
0108     bool check_normal() const { return check_normal_; }
0109 
0110     //! Enable/disable failure state checking
0111     void check_failure(bool value) { check_failure_ = value; }
0112     //! Whether failure checking is enabled
0113     bool check_failure() const { return check_failure_; }
0114 
0115     //! Enable/disable zero-step distance checking
0116     void check_zero_distance(bool value) { check_zero_distance_ = value; }
0117     //! Whether zero-distance checking is enabled
0118     bool check_zero_distance() const { return check_zero_distance_; }
0119 
0120     //! Check the safety when doing find-next-distance
0121     void check_next_safety(bool value) { check_next_safety_ = value; }
0122 
0123     //! Canonical volume parameters (if available)
0124     SPConstVolumes const& volumes() const { return volumes_; }
0125     //! Geometry interface (if available)
0126     SPConstGeoI const& geo_interface() const { return geo_interface_; }
0127     //! Length scale
0128     UnitLength unit_length() const { return unit_length_; }
0129 
0130     //// GEO TRACK INTERFACE ////
0131 
0132     // Initialize the state
0133     CheckedGeoTrackView& operator=(GeoTrackInitializer const& init) final;
0134 
0135     // Physical state
0136     Real3 const& pos() const final { return t_->pos(); }
0137     Real3 const& dir() const final { return t_->dir(); }
0138 
0139     // Canonical volume state
0140     VolumeId volume_id() const final { return t_->volume_id(); }
0141     VolumeInstanceId volume_instance_id() const final
0142     {
0143         return t_->volume_instance_id();
0144     }
0145     VolumeLevelId volume_level() const final { return t_->volume_level(); }
0146     void volume_instance_id(Span<VolumeInstanceId> levels) const final
0147     {
0148         t_->volume_instance_id(levels);
0149     }
0150     void foreach_volume_path(VolPathVisitor visit) const final
0151     {
0152         t_->foreach_volume_path(std::move(visit));
0153     }
0154 
0155     // Implementation volume ID
0156     ImplVolumeId impl_volume_id() const final { return t_->impl_volume_id(); }
0157 
0158     // State flags
0159     bool is_outside() const final { return t_->is_outside(); }
0160     bool failed() const final { return t_->failed(); }
0161 
0162     // Surface state
0163     bool is_on_boundary() const final { return t_->is_on_boundary(); }
0164     Real3 normal() const final { return t_->normal(); }
0165 
0166     // Derive the geometry status from the inner track
0167     GeoStatus geo_status() const final;
0168 
0169     // Calculate or return the safety up to an infinite distance
0170     real_type find_safety() final;
0171 
0172     // Calculate or return the safety up to the given distance
0173     real_type find_safety(real_type max_safety) final;
0174 
0175     // Change the direction
0176     void set_dir(Real3 const&) final;
0177 
0178     // Find the distance to the next boundary
0179     Propagation find_next_step(real_type max_distance) final;
0180 
0181     // Move a linear step fraction
0182     void move_internal(real_type step) final;
0183 
0184     // Move within the safety distance to a specific point
0185     void move_internal(Real3 const& pos) final;
0186 
0187     // Move to the boundary in preparation for crossing it
0188     void move_to_boundary() final;
0189 
0190     // Cross from one side of the current surface to the other
0191     void cross_boundary() final;
0192 
0193   private:
0194     UPTrack t_;
0195     Logger log_;
0196 
0197     // Metadata
0198     SPConstVolumes volumes_;
0199     SPConstGeoI geo_interface_;
0200     UnitLength unit_length_;
0201 
0202     // Configuration flags
0203     bool check_normal_{true};
0204     bool check_failure_{true};
0205     bool check_next_safety_{true};
0206     bool check_safety_{true};
0207     bool check_zero_distance_{true};
0208 
0209     // Counters
0210     struct
0211     {
0212         size_type intersect{0};
0213         size_type safety{0};
0214     } count_;
0215 
0216     //// Temporary state ////
0217 
0218     //! Check during a move_internal(Real3) that the updated point is within
0219     //! the same volume
0220     bool checked_internal_{false};
0221     //! Store the maximum straight-line distance that has been found
0222     std::optional<real_type> next_step_;
0223     //! Whether the next straight-line distance (if found) is a boundary
0224     bool next_is_boundary_{false};
0225 };
0226 
0227 //---------------------------------------------------------------------------//
0228 //! Geometry exception thrown by checked assertions
0229 class CheckedGeoError : public RuntimeError
0230 {
0231   public:
0232     CheckedGeoError(RuntimeErrorDetails&& r) : RuntimeError(std::move(r)) {}
0233 };
0234 
0235 //---------------------------------------------------------------------------//
0236 // FREE FUNCTIONS
0237 //---------------------------------------------------------------------------//
0238 
0239 std::ostream& operator<<(std::ostream&, CheckedGeoTrackView const&);
0240 
0241 //---------------------------------------------------------------------------//
0242 }  // namespace celeritas