|
||||
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/transform/Transformation.hh 0007 //---------------------------------------------------------------------------// 0008 #pragma once 0009 0010 #include <algorithm> 0011 0012 #include "corecel/cont/Span.hh" 0013 #include "corecel/math/ArrayOperators.hh" 0014 #include "geocel/Types.hh" 0015 #include "orange/MatrixUtils.hh" 0016 #include "orange/OrangeTypes.hh" 0017 0018 namespace celeritas 0019 { 0020 class Translation; 0021 class SignedPermutation; 0022 0023 //---------------------------------------------------------------------------// 0024 /*! 0025 * Apply transformations with rotation and/or reflection. 0026 * 0027 * \note The nomenclature in this class assumes the translation vector and 0028 * rotation matrix given represent "daughter-to-parent"! This is because we 0029 * think of rotations being with respect to the daughter's origin rather than 0030 * the parent's. 0031 * 0032 * This class enables transforms between daughter and parent coordinate 0033 * system. The transfer from a daughter into a parent system ("up" in a 0034 * hierarchy of universes) is 0035 * \f[ 0036 \mathbf{r}_p = \mathbf{R}\mathbf{r}_d + \mathbf{t}\:, 0037 * \f] 0038 * Where the subscripts \e p,d refer to the parent and daughter coordinate 0039 * systems, respectively. The vector \b t is a translation vector. To go 0040 * from the parent into the daughter system ("down" in a universe hierarchy) we 0041 * apply the inverse: 0042 * \f[ 0043 \mathbf{r}_d = \mathbf{R}^T(\mathbf{r}_p - \mathbf{t})\:. 0044 * \f] 0045 * where the transpose of \b R is equal to its inverse because the matrix is 0046 * unitary. 0047 * 0048 * The rotation matrix is indexed with C ordering, [i][j]. 0049 */ 0050 class Transformation 0051 { 0052 public: 0053 //@{ 0054 //! \name Type aliases 0055 using StorageSpan = Span<real_type const, 12>; 0056 using Mat3 = SquareMatrixReal3; 0057 //@} 0058 0059 //! Transformation type identifier 0060 static CELER_CONSTEXPR_FUNCTION TransformType transform_type() 0061 { 0062 return TransformType::transformation; 0063 } 0064 0065 public: 0066 // Construct by inverting a parent-to-daughter transformation 0067 static Transformation from_inverse(Mat3 const& rot, Real3 const& trans); 0068 0069 //// CONSTRUCTORS //// 0070 0071 // Construct and check the input 0072 Transformation(Mat3 const& rot, Real3 const& trans); 0073 0074 // Construct from an identity transformation + translation 0075 Transformation(); 0076 0077 // Promote from a translation 0078 explicit Transformation(Translation const&); 0079 0080 // Promote from a signed permutation 0081 explicit Transformation(SignedPermutation const&); 0082 0083 // Construct inline from storage 0084 explicit inline CELER_FUNCTION Transformation(StorageSpan); 0085 0086 //// ACCESSORS //// 0087 0088 //! Rotation matrix 0089 CELER_FORCEINLINE_FUNCTION Mat3 const& rotation() const { return rot_; } 0090 0091 //! Translation vector 0092 CELER_FORCEINLINE_FUNCTION Real3 const& translation() const 0093 { 0094 return tra_; 0095 } 0096 0097 //! Get a view to the data for type-deleted storage 0098 CELER_FUNCTION StorageSpan data() const { return {&rot_[0][0], 12}; } 0099 0100 //// CALCULATION //// 0101 0102 // Transform from daughter to parent 0103 [[nodiscard]] inline CELER_FUNCTION Real3 0104 transform_up(Real3 const& pos) const; 0105 0106 // Transform from parent to daughter 0107 [[nodiscard]] inline CELER_FUNCTION Real3 0108 transform_down(Real3 const& parent_pos) const; 0109 0110 // Rotate from daughter to parent 0111 [[nodiscard]] inline CELER_FUNCTION Real3 rotate_up(Real3 const& dir) const; 0112 0113 // Rotate from parent to daughter 0114 [[nodiscard]] inline CELER_FUNCTION Real3 0115 rotate_down(Real3 const& parent_dir) const; 0116 0117 // Calculate the inverse during preprocessing 0118 Transformation calc_inverse() const; 0119 0120 private: 0121 Mat3 rot_; 0122 Real3 tra_; 0123 }; 0124 0125 //---------------------------------------------------------------------------// 0126 //!@{ 0127 //! Host-only comparators 0128 inline bool operator==(Transformation const& a, Transformation const& b) 0129 { 0130 auto a_data = a.data(); 0131 return std::equal(a_data.begin(), a_data.end(), b.data().begin()); 0132 } 0133 0134 inline bool operator!=(Transformation const& a, Transformation const& b) 0135 { 0136 return !(a == b); 0137 } 0138 //!@} 0139 0140 //---------------------------------------------------------------------------// 0141 // INLINE DEFINITIONS 0142 //---------------------------------------------------------------------------// 0143 /*! 0144 * Construct inline from storage. 0145 */ 0146 CELER_FUNCTION Transformation::Transformation(StorageSpan s) 0147 : rot_{Real3{s[0], s[1], s[2]}, 0148 Real3{s[3], s[4], s[5]}, 0149 Real3{s[6], s[7], s[8]}} 0150 , tra_{s[9], s[10], s[11]} 0151 { 0152 } 0153 0154 //---------------------------------------------------------------------------// 0155 /*! 0156 * Transform from daughter to parent. 0157 * 0158 * Apply the rotation matrix, add the translation. 0159 */ 0160 CELER_FUNCTION Real3 Transformation::transform_up(Real3 const& pos) const 0161 { 0162 return gemv(real_type{1}, rot_, pos, real_type{1}, tra_); 0163 } 0164 0165 //---------------------------------------------------------------------------// 0166 /*! 0167 * Transform from parent to daughter. 0168 * 0169 * Subtract the translation, then apply the inverse of the rotation matrix (its 0170 * transpose). 0171 */ 0172 CELER_FUNCTION Real3 Transformation::transform_down(Real3 const& pos) const 0173 { 0174 return gemv(matrix::transpose, rot_, pos - tra_); 0175 } 0176 0177 //---------------------------------------------------------------------------// 0178 /*! 0179 * Rotate from daughter to parent. 0180 */ 0181 CELER_FUNCTION Real3 Transformation::rotate_up(Real3 const& d) const 0182 { 0183 return gemv(rot_, d); 0184 } 0185 0186 //---------------------------------------------------------------------------// 0187 /*! 0188 * Rotate from parent to daughter. 0189 */ 0190 CELER_FUNCTION Real3 Transformation::rotate_down(Real3 const& d) const 0191 { 0192 return gemv(matrix::transpose, rot_, d); 0193 } 0194 0195 //---------------------------------------------------------------------------// 0196 } // namespace celeritas
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |