Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2023-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/Plane.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include "corecel/Macros.hh"
0011 #include "corecel/cont/Array.hh"
0012 #include "corecel/cont/Span.hh"
0013 #include "corecel/math/ArrayUtils.hh"
0014 #include "orange/OrangeTypes.hh"
0015 
0016 namespace celeritas
0017 {
0018 //---------------------------------------------------------------------------//
0019 template<Axis T>
0020 class PlaneAligned;
0021 
0022 //---------------------------------------------------------------------------//
0023 /*!
0024  * Arbitrarily oriented plane.
0025  *
0026  * A plane is a first-order quadric that satisfies \f[
0027     ax + bx + cz - d = 0
0028     \f]
0029  */
0030 class Plane
0031 {
0032   public:
0033     //@{
0034     //! \name Type aliases
0035     using Intersections = Array<real_type, 1>;
0036     using StorageSpan = Span<real_type const, 4>;
0037     //@}
0038 
0039     //// CLASS ATTRIBUTES ////
0040 
0041     //! Surface type identifier
0042     static CELER_CONSTEXPR_FUNCTION SurfaceType surface_type()
0043     {
0044         return SurfaceType::p;
0045     }
0046 
0047     //! Safety is intersection along surface normal
0048     static CELER_CONSTEXPR_FUNCTION bool simple_safety() { return true; }
0049 
0050   public:
0051     //// CONSTRUCTORS ////
0052 
0053     // Construct with normal and point
0054     explicit inline CELER_FUNCTION Plane(Real3 const& n, Real3 const& p);
0055 
0056     // Construct with normal and displacement
0057     explicit inline CELER_FUNCTION Plane(Real3 const& n, real_type d);
0058 
0059     // Construct from raw data
0060     template<class R>
0061     explicit inline CELER_FUNCTION Plane(Span<R, StorageSpan::extent>);
0062 
0063     // Promote from an axis-aligned plane
0064     template<Axis T>
0065     explicit Plane(PlaneAligned<T> const& other) noexcept;
0066 
0067     //// ACCESSORS ////
0068 
0069     //! Normal to the plane
0070     CELER_FUNCTION Real3 const& normal() const { return normal_; }
0071 
0072     //! Distance from the origin along the normal to the plane
0073     CELER_FUNCTION real_type displacement() const { return d_; }
0074 
0075     //! Get a view to the data for type-deleted storage
0076     CELER_FUNCTION StorageSpan data() const { return {&normal_[0], 4}; }
0077 
0078     //// CALCULATION ////
0079 
0080     // Determine the sense of the position relative to this surface
0081     inline CELER_FUNCTION SignedSense calc_sense(Real3 const& pos) const;
0082 
0083     // Calculate all possible straight-line intersections with this surface
0084     inline CELER_FUNCTION Intersections calc_intersections(
0085         Real3 const& pos, Real3 const& dir, SurfaceState on_surface) const;
0086 
0087     // Calculate outward normal at a position on the surface
0088     inline CELER_FUNCTION Real3 calc_normal(Real3 const&) const;
0089 
0090   private:
0091     // Normal to plane (a,b,c)
0092     Real3 normal_;
0093 
0094     // n \dot P (d)
0095     real_type d_;
0096 };
0097 
0098 //---------------------------------------------------------------------------//
0099 // INLINE DEFINITIONS
0100 //---------------------------------------------------------------------------//
0101 /*!
0102  * Construct with unit normal and point.
0103  *
0104  * Displacement is the dot product of the point and the normal.
0105  */
0106 CELER_FUNCTION Plane::Plane(Real3 const& n, Real3 const& p)
0107     : Plane{n, dot_product(n, p)}
0108 {
0109 }
0110 
0111 //---------------------------------------------------------------------------//
0112 /*!
0113  * Construct with unit normal and displacement.
0114  */
0115 CELER_FUNCTION Plane::Plane(Real3 const& n, real_type d) : normal_{n}, d_{d}
0116 {
0117     CELER_EXPECT(is_soft_unit_vector(normal_));
0118 }
0119 
0120 //---------------------------------------------------------------------------//
0121 /*!
0122  * Construct from raw data.
0123  */
0124 template<class R>
0125 CELER_FUNCTION Plane::Plane(Span<R, StorageSpan::extent> data)
0126     : normal_{data[0], data[1], data[2]}, d_{data[3]}
0127 {
0128 }
0129 
0130 //---------------------------------------------------------------------------//
0131 /*!
0132  * Determine the sense of the position relative to this surface.
0133  */
0134 CELER_FUNCTION SignedSense Plane::calc_sense(Real3 const& pos) const
0135 {
0136     return real_to_sense(dot_product(normal_, pos) - d_);
0137 }
0138 
0139 //---------------------------------------------------------------------------//
0140 /*!
0141  * Calculate all possible straight-line intersections with this surface.
0142  */
0143 CELER_FUNCTION auto
0144 Plane::calc_intersections(Real3 const& pos,
0145                           Real3 const& dir,
0146                           SurfaceState on_surface) const -> Intersections
0147 {
0148     real_type const n_dir = dot_product(normal_, dir);
0149     if (on_surface == SurfaceState::off && n_dir != 0)
0150     {
0151         real_type const n_pos = dot_product(normal_, pos);
0152         real_type dist = (d_ - n_pos) / n_dir;
0153         if (dist > 0)
0154         {
0155             return {dist};
0156         }
0157     }
0158     return {no_intersection()};
0159 }
0160 
0161 //---------------------------------------------------------------------------//
0162 /*!
0163  * Calculate outward normal at a position on the surface.
0164  */
0165 CELER_FORCEINLINE_FUNCTION Real3 Plane::calc_normal(Real3 const&) const
0166 {
0167     return normal_;
0168 }
0169 
0170 //---------------------------------------------------------------------------//
0171 }  // namespace celeritas