Warning, file /include/orange/surf/GeneralQuadric.hh was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/Config.hh"
0010
0011 #include "corecel/Types.hh"
0012 #include "corecel/cont/Array.hh"
0013 #include "corecel/cont/Span.hh"
0014 #include "corecel/math/ArrayUtils.hh"
0015 #include "orange/OrangeTypes.hh"
0016 #include "orange/SenseUtils.hh"
0017
0018 #include "detail/QuadraticSolver.hh"
0019
0020 namespace celeritas
0021 {
0022
0023 class SimpleQuadric;
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 class GeneralQuadric
0041 {
0042 public:
0043
0044
0045 using Intersections = Array<real_type, 2>;
0046 using StorageSpan = Span<real_type const, 10>;
0047 using SpanConstReal3 = Span<real_type const, 3>;
0048
0049
0050
0051
0052
0053 static CELER_CONSTEXPR_FUNCTION SurfaceType surface_type()
0054 {
0055 return SurfaceType::gq;
0056 }
0057
0058
0059 static CELER_CONSTEXPR_FUNCTION bool simple_safety() { return false; }
0060
0061 public:
0062
0063
0064
0065 explicit GeneralQuadric(Real3 const& abc,
0066 Real3 const& def,
0067 Real3 const& ghi,
0068 real_type j);
0069
0070
0071 template<class R>
0072 explicit inline CELER_FUNCTION GeneralQuadric(Span<R, StorageSpan::extent>);
0073
0074
0075 explicit GeneralQuadric(SimpleQuadric const& other) noexcept(
0076 !CELERITAS_DEBUG);
0077
0078
0079
0080
0081 CELER_FUNCTION SpanConstReal3 second() const { return {&a_, 3}; }
0082
0083
0084 CELER_FUNCTION SpanConstReal3 cross() const { return {&d_, 3}; }
0085
0086
0087 CELER_FUNCTION SpanConstReal3 first() const { return {&g_, 3}; }
0088
0089
0090 CELER_FUNCTION real_type zeroth() const { return j_; }
0091
0092
0093 CELER_FUNCTION StorageSpan data() const { return {&a_, 10}; }
0094
0095
0096
0097
0098 inline CELER_FUNCTION SignedSense calc_sense(Real3 const& pos) const;
0099
0100
0101 inline CELER_FUNCTION Intersections calc_intersections(
0102 Real3 const& pos, Real3 const& dir, SurfaceState on_surface) const;
0103
0104
0105 inline CELER_FUNCTION Real3 calc_normal(Real3 const& pos) const;
0106
0107 private:
0108
0109 real_type a_, b_, c_;
0110
0111 real_type d_, e_, f_;
0112
0113 real_type g_, h_, i_;
0114
0115 real_type j_;
0116 };
0117
0118
0119
0120
0121
0122
0123
0124 template<class R>
0125 CELER_FUNCTION GeneralQuadric::GeneralQuadric(Span<R, StorageSpan::extent> data)
0126 : a_(data[0])
0127 , b_(data[1])
0128 , c_(data[2])
0129 , d_(data[3])
0130 , e_(data[4])
0131 , f_(data[5])
0132 , g_(data[6])
0133 , h_(data[7])
0134 , i_(data[8])
0135 , j_(data[9])
0136 {
0137 }
0138
0139
0140
0141
0142
0143 CELER_FUNCTION SignedSense GeneralQuadric::calc_sense(Real3 const& pos) const
0144 {
0145 real_type const x = pos[0];
0146 real_type const y = pos[1];
0147 real_type const z = pos[2];
0148
0149 real_type result = (a_ * x + d_ * y + f_ * z + g_) * x
0150 + (b_ * y + e_ * z + h_) * y + (c_ * z + i_) * z + j_;
0151
0152 return real_to_sense(result);
0153 }
0154
0155
0156
0157
0158
0159 CELER_FUNCTION auto
0160 GeneralQuadric::calc_intersections(Real3 const& pos,
0161 Real3 const& dir,
0162 SurfaceState on_surface) const -> Intersections
0163 {
0164 real_type const x = pos[0];
0165 real_type const y = pos[1];
0166 real_type const z = pos[2];
0167 real_type const u = dir[0];
0168 real_type const v = dir[1];
0169 real_type const w = dir[2];
0170
0171
0172 real_type a = (a_ * u + d_ * v) * u + (b_ * v + e_ * w) * v
0173 + (c_ * w + f_ * u) * w;
0174 real_type b = (2 * a_ * x + d_ * y + f_ * z + g_) * u
0175 + (2 * b_ * y + d_ * x + e_ * z + h_) * v
0176 + (2 * c_ * z + e_ * y + f_ * x + i_) * w;
0177 real_type c = ((a_ * x + d_ * y + g_) * x + (b_ * y + e_ * z + h_) * y
0178 + (c_ * z + f_ * x + i_) * z + j_);
0179
0180 return detail::QuadraticSolver::solve_general(a, b / 2, c, on_surface);
0181 }
0182
0183
0184
0185
0186
0187 CELER_FUNCTION Real3 GeneralQuadric::calc_normal(Real3 const& pos) const
0188 {
0189 real_type const x = pos[0];
0190 real_type const y = pos[1];
0191 real_type const z = pos[2];
0192
0193 Real3 norm;
0194 norm[0] = 2 * a_ * x + d_ * y + f_ * z + g_;
0195 norm[1] = 2 * b_ * y + d_ * x + e_ * z + h_;
0196 norm[2] = 2 * c_ * z + e_ * y + f_ * x + i_;
0197
0198 return make_unit_vector(norm);
0199 }
0200
0201
0202 }