Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 09:07:50

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