Rotation.hpp
Go to the documentation of this file.
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 /// \file
5 /// Defines the class Rotation.
6 
7 #pragma once
8 
9 #include <array>
10 #include <boost/optional.hpp>
11 #include <cstddef>
12 #include <limits>
13 
15 #include "Utilities/TypeTraits.hpp"
16 
17 namespace PUP {
18 class er;
19 } // namespace PUP
20 
21 namespace CoordinateMaps {
22 
23 /// \cond HIDDEN_SYMBOLS
24 template <size_t Dim>
25 class Rotation;
26 /// \endcond
27 
28 /*!
29  * \ingroup CoordinateMapsGroup
30  * \brief Spatial rotation in two dimensions.
31  *
32  * Let \f$(R,\Phi)\f$ be the polar coordinates associated with
33  * \f$(\xi,\eta)\f$.
34  * Let \f$(r,\phi)\f$ be the polar coordinates associated with \f$(x,y)\f$.
35  * Applies the spatial rotation \f$\phi = \Phi + \alpha\f$.
36  *
37  * The formula for the mapping is:
38  *\f{eqnarray*}
39  x &=& \xi \cos \alpha - \eta \sin \alpha \\
40  y &=& \xi \sin \alpha + \eta \cos \alpha
41  \f}.
42  */
43 template <>
44 class Rotation<2> {
45  public:
46  static constexpr size_t dim = 2;
47 
48  /// Constructor.
49  ///
50  /// \param rotation_angle the angle \f$\alpha\f$ (in radians).
51  explicit Rotation(double rotation_angle);
52  Rotation() = default;
53  ~Rotation() = default;
54  Rotation(const Rotation&) = default;
55  Rotation& operator=(const Rotation&) = default;
56  Rotation(Rotation&&) noexcept = default; // NOLINT
57  Rotation& operator=(Rotation&&) = default;
58 
59  template <typename T>
61  const std::array<T, 2>& source_coords) const noexcept;
62 
63  boost::optional<std::array<double, 2>> inverse(
64  const std::array<double, 2>& target_coords) const noexcept;
65 
66  template <typename T>
67  tnsr::Ij<tt::remove_cvref_wrap_t<T>, 2, Frame::NoFrame> jacobian(
68  const std::array<T, 2>& source_coords) const noexcept;
69 
70  template <typename T>
71  tnsr::Ij<tt::remove_cvref_wrap_t<T>, 2, Frame::NoFrame> inv_jacobian(
72  const std::array<T, 2>& source_coords) const noexcept;
73 
74  void pup(PUP::er& p); // NOLINT
75 
76  bool is_identity() const noexcept { return is_identity_; }
77 
78  private:
79  friend bool operator==(const Rotation<2>& lhs,
80  const Rotation<2>& rhs) noexcept;
81 
82  double rotation_angle_{std::numeric_limits<double>::signaling_NaN()};
83  tnsr::ij<double, 2, Frame::Grid> rotation_matrix_{
85  bool is_identity_{false};
86 };
87 
88 bool operator!=(const Rotation<2>& lhs, const Rotation<2>& rhs) noexcept;
89 
90 /*!
91  * \ingroup CoordinateMapsGroup
92  * \brief Spatial rotation in three dimensions using Euler angles
93  *
94  * Rotation angles should be specified in degrees.
95  * First rotation \f$\alpha\f$ is about z axis.
96  * Second rotation \f$\beta\f$ is about rotated y axis.
97  * Third rotation \f$\gamma\f$ is about rotated z axis.
98  * These rotations are of the \f$(\xi,\eta,\zeta)\f$ coordinate system with
99  * respect
100  * to the grid coordinates \f$(x,y,z)\f$.
101  *
102  * The formula for the mapping is:
103  * \f{eqnarray*}
104  * x &=& \xi (\cos\gamma \cos\beta \cos\alpha - \sin\gamma \sin\alpha)
105  * + \eta (-\sin\gamma \cos\beta \cos\alpha - \cos\gamma \sin\alpha)
106  * + \zeta \sin\beta \cos\alpha \\
107  * y &=& \xi (\cos\gamma \cos\beta \sin\alpha + \sin\gamma \cos\alpha)
108  * + \eta (-\sin\gamma \cos\beta \sin\alpha + \cos\gamma \cos\alpha)
109  * + \zeta \sin\beta \sin\alpha \\
110  * z &=& -\xi \cos\gamma \sin\beta + \eta \sin\gamma \sin\beta
111  * + \zeta \cos\beta
112  * \f}
113  */
114 template <>
115 class Rotation<3> {
116  public:
117  static constexpr size_t dim = 3;
118 
119  /// Constructor.
120  ///
121  /// \param rotation_about_z the angle \f$\alpha\f$ (in radians).
122  /// \param rotation_about_rotated_y the angle \f$\beta\f$ (in radians).
123  /// \param rotation_about_rotated_z the angle \f$\gamma\f$ (in radians).
124  Rotation(double rotation_about_z, double rotation_about_rotated_y,
125  double rotation_about_rotated_z);
126  Rotation() = default;
127  ~Rotation() = default;
128  Rotation(const Rotation&) = default;
129  Rotation& operator=(const Rotation&) = default;
130  Rotation(Rotation&&) noexcept = default; // NOLINT
131  Rotation& operator=(Rotation&&) = default;
132 
133  template <typename T>
135  const std::array<T, 3>& source_coords) const noexcept;
136 
137  boost::optional<std::array<double, 3>> inverse(
138  const std::array<double, 3>& target_coords) const noexcept;
139 
140  template <typename T>
141  tnsr::Ij<tt::remove_cvref_wrap_t<T>, 3, Frame::NoFrame> jacobian(
142  const std::array<T, 3>& source_coords) const noexcept;
143 
144  template <typename T>
145  tnsr::Ij<tt::remove_cvref_wrap_t<T>, 3, Frame::NoFrame> inv_jacobian(
146  const std::array<T, 3>& source_coords) const noexcept;
147 
148  void pup(PUP::er& p); // NOLINT
149 
150  bool is_identity() const noexcept { return is_identity_; }
151 
152  private:
153  friend bool operator==(const Rotation<3>& lhs,
154  const Rotation<3>& rhs) noexcept;
155 
156  double rotation_about_z_{std::numeric_limits<double>::signaling_NaN()};
157  double rotation_about_rotated_y_{
159  double rotation_about_rotated_z_{
161  tnsr::ij<double, 3, Frame::Grid> rotation_matrix_{
163  bool is_identity_{false};
164 };
165 
166 bool operator!=(const Rotation<3>& lhs, const Rotation<3>& rhs) noexcept;
167 
168 } // namespace CoordinateMaps
Definition: Strahlkorper.hpp:14
T signaling_NaN(T... args)
Spatial rotation in three dimensions using Euler angles.
Definition: Rotation.hpp:115
Contains all coordinate maps.
Definition: Affine.cpp:14
Spatial rotation in two dimensions.
Definition: Rotation.hpp:44
Defines classes for Tensor.
Represents an index that is not in a known frame, e.g. some internal intermediate frame that is irrel...
Definition: IndexType.hpp:48
Defines type traits, some of which are future STL type_traits header.