Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:05:57

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2022-2024 UT-Battelle, LLC, and other Celeritas developers.
0003 // See the top-level COPYRIGHT file for details.
0004 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0005 //---------------------------------------------------------------------------//
0006 //! \file orange/surf/SphereCentered.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include "corecel/Types.hh"
0011 #include "corecel/cont/Array.hh"
0012 #include "corecel/cont/Span.hh"
0013 #include "corecel/math/Algorithms.hh"
0014 #include "corecel/math/ArrayUtils.hh"
0015 
0016 #include "detail/QuadraticSolver.hh"
0017 
0018 namespace celeritas
0019 {
0020 //---------------------------------------------------------------------------//
0021 /*!
0022  * Sphere centered at the origin.
0023  */
0024 class SphereCentered
0025 {
0026   public:
0027     //@{
0028     //! \name Type aliases
0029     using Intersections = Array<real_type, 2>;
0030     using StorageSpan = Span<real_type const, 1>;
0031     //@}
0032 
0033     //// CLASS ATTRIBUTES ////
0034 
0035     //! Surface type identifier
0036     static CELER_CONSTEXPR_FUNCTION SurfaceType surface_type()
0037     {
0038         return SurfaceType::sc;
0039     }
0040 
0041     //! Safety is intersection along surface normal
0042     static CELER_CONSTEXPR_FUNCTION bool simple_safety() { return true; }
0043 
0044   public:
0045     //// CONSTRUCTORS ////
0046 
0047     // Construct with square of radius for simplification
0048     static inline SphereCentered from_radius_sq(real_type rsq);
0049 
0050     // Construct with origin and radius
0051     explicit inline CELER_FUNCTION SphereCentered(real_type radius);
0052 
0053     // Construct from raw data
0054     template<class R>
0055     explicit inline CELER_FUNCTION SphereCentered(Span<R, StorageSpan::extent>);
0056 
0057     //// ACCESSORS ////
0058 
0059     //! Square of the radius
0060     CELER_FUNCTION real_type radius_sq() const { return radius_sq_; }
0061 
0062     //! Get a view to the data for type-deleted storage
0063     CELER_FUNCTION StorageSpan data() const { return {&radius_sq_, 1}; }
0064 
0065     //// CALCULATION ////
0066 
0067     // Determine the sense of the position relative to this surface
0068     inline CELER_FUNCTION SignedSense calc_sense(Real3 const& pos) const;
0069 
0070     // Calculate all possible straight-line intersections with this surface
0071     inline CELER_FUNCTION Intersections calc_intersections(
0072         Real3 const& pos, Real3 const& dir, SurfaceState on_surface) const;
0073 
0074     // Calculate outward normal at a position
0075     inline CELER_FUNCTION Real3 calc_normal(Real3 const& pos) const;
0076 
0077   private:
0078     // Square of the radius
0079     real_type radius_sq_;
0080 
0081     //! Private default constructor for manual construction
0082     SphereCentered() = default;
0083 };
0084 
0085 //---------------------------------------------------------------------------//
0086 // INLINE DEFINITIONS
0087 //---------------------------------------------------------------------------//
0088 /*!
0089  * Construct from the square of the radius.
0090  *
0091  * This is used for surface simplification.
0092  */
0093 SphereCentered SphereCentered::from_radius_sq(real_type rsq)
0094 {
0095     CELER_EXPECT(rsq > 0);
0096     SphereCentered result;
0097     result.radius_sq_ = rsq;
0098     return result;
0099 }
0100 
0101 //---------------------------------------------------------------------------//
0102 /*!
0103  * Construct with sphere radius.
0104  */
0105 CELER_FUNCTION SphereCentered::SphereCentered(real_type radius)
0106     : radius_sq_(ipow<2>(radius))
0107 {
0108     CELER_EXPECT(radius > 0);
0109 }
0110 
0111 //---------------------------------------------------------------------------//
0112 /*!
0113  * Construct from raw data.
0114  */
0115 template<class R>
0116 CELER_FUNCTION SphereCentered::SphereCentered(Span<R, StorageSpan::extent> data)
0117     : radius_sq_{data[0]}
0118 {
0119 }
0120 
0121 //---------------------------------------------------------------------------//
0122 /*!
0123  * Determine the sense of the position relative to this surface.
0124  */
0125 CELER_FUNCTION SignedSense SphereCentered::calc_sense(Real3 const& pos) const
0126 {
0127     return real_to_sense(dot_product(pos, pos) - radius_sq_);
0128 }
0129 
0130 //---------------------------------------------------------------------------//
0131 /*!
0132  * Calculate all possible straight-line intersections with this surface.
0133  */
0134 CELER_FUNCTION auto
0135 SphereCentered::calc_intersections(Real3 const& pos,
0136                                    Real3 const& dir,
0137                                    SurfaceState on_surface) const -> Intersections
0138 {
0139     detail::QuadraticSolver solve_quadric(real_type(1), dot_product(pos, dir));
0140     if (on_surface == SurfaceState::off)
0141     {
0142         return solve_quadric(dot_product(pos, pos) - radius_sq_);
0143     }
0144     else
0145     {
0146         return solve_quadric();
0147     }
0148 }
0149 
0150 //---------------------------------------------------------------------------//
0151 /*!
0152  * Calculate outward normal at a position.
0153  */
0154 CELER_FUNCTION Real3 SphereCentered::calc_normal(Real3 const& pos) const
0155 {
0156     return make_unit_vector(pos);
0157 }
0158 
0159 //---------------------------------------------------------------------------//
0160 }  // namespace celeritas