File indexing completed on 2025-01-18 10:05:57
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include "corecel/Macros.hh"
0011 #include "corecel/cont/Array.hh"
0012 #include "corecel/cont/Span.hh"
0013 #include "orange/OrangeTypes.hh"
0014
0015 namespace celeritas
0016 {
0017
0018
0019
0020
0021 template<Axis T>
0022 class PlaneAligned
0023 {
0024 public:
0025
0026
0027 using Intersections = Array<real_type, 1>;
0028 using StorageSpan = Span<real_type const, 1>;
0029
0030
0031
0032
0033
0034 static CELER_CONSTEXPR_FUNCTION SurfaceType surface_type();
0035
0036
0037 static CELER_CONSTEXPR_FUNCTION bool simple_safety() { return true; }
0038
0039 public:
0040
0041
0042
0043 explicit inline CELER_FUNCTION PlaneAligned(real_type position);
0044
0045
0046 template<class R>
0047 explicit inline CELER_FUNCTION PlaneAligned(Span<R, StorageSpan::extent>);
0048
0049
0050
0051
0052 CELER_FUNCTION real_type position() const { return position_; }
0053
0054
0055 CELER_FUNCTION StorageSpan data() const { return {&position_, 1}; }
0056
0057
0058 inline CELER_FUNCTION Real3 calc_normal() const;
0059
0060
0061
0062
0063 inline CELER_FUNCTION SignedSense calc_sense(Real3 const& pos) const;
0064
0065
0066 inline CELER_FUNCTION Intersections calc_intersections(
0067 Real3 const& pos, Real3 const& dir, SurfaceState on_surface) const;
0068
0069
0070 inline CELER_FUNCTION Real3 calc_normal(Real3 const& pos) const;
0071
0072 private:
0073
0074 real_type position_;
0075 };
0076
0077
0078
0079
0080
0081 using PlaneX = PlaneAligned<Axis::x>;
0082 using PlaneY = PlaneAligned<Axis::y>;
0083 using PlaneZ = PlaneAligned<Axis::z>;
0084
0085
0086
0087
0088
0089
0090
0091 template<Axis T>
0092 CELER_CONSTEXPR_FUNCTION SurfaceType PlaneAligned<T>::surface_type()
0093 {
0094 return T == Axis::x ? SurfaceType::px
0095 : T == Axis::y ? SurfaceType::py
0096 : T == Axis::z ? SurfaceType::pz
0097 : SurfaceType::size_;
0098 }
0099
0100
0101
0102
0103
0104 template<Axis T>
0105 CELER_FUNCTION PlaneAligned<T>::PlaneAligned(real_type position)
0106 : position_(position)
0107 {
0108 }
0109
0110
0111
0112
0113
0114 template<Axis T>
0115 template<class R>
0116 CELER_FUNCTION PlaneAligned<T>::PlaneAligned(Span<R, StorageSpan::extent> data)
0117 : position_(data[0])
0118 {
0119 }
0120
0121
0122
0123
0124
0125 template<Axis T>
0126 CELER_FUNCTION Real3 PlaneAligned<T>::calc_normal() const
0127 {
0128 Real3 norm{0, 0, 0};
0129
0130 norm[to_int(T)] = 1.;
0131 return norm;
0132 }
0133
0134
0135
0136
0137
0138 template<Axis T>
0139 CELER_FUNCTION SignedSense PlaneAligned<T>::calc_sense(Real3 const& pos) const
0140 {
0141 return real_to_sense(pos[to_int(T)] - position_);
0142 }
0143
0144
0145
0146
0147
0148 template<Axis T>
0149 CELER_FUNCTION auto
0150 PlaneAligned<T>::calc_intersections(Real3 const& pos,
0151 Real3 const& dir,
0152 SurfaceState on_surface) const -> Intersections
0153 {
0154 real_type const n_dir = dir[to_int(T)];
0155 if (on_surface == SurfaceState::off && n_dir != 0)
0156 {
0157 real_type const n_pos = pos[to_int(T)];
0158 real_type dist = (position_ - n_pos) / n_dir;
0159 if (dist > 0)
0160 {
0161 return {dist};
0162 }
0163 }
0164 return {no_intersection()};
0165 }
0166
0167
0168
0169
0170
0171 template<Axis T>
0172 CELER_FUNCTION Real3 PlaneAligned<T>::calc_normal(Real3 const&) const
0173 {
0174 return this->calc_normal();
0175 }
0176
0177
0178 }