SpECTRE  v2024.05.11
domain::CoordinateMaps::TimeDependent::Rotation< Dim > Class Template Reference

Time-dependent spatial rotation in two or three dimensions. More...

#include <Rotation.hpp>

Public Member Functions

 Rotation (std::string function_of_time_name)
 
template<typename T >
std::array< tt::remove_cvref_wrap_t< T >, Dim > operator() (const std::array< T, Dim > &source_coords, double time, const std::unordered_map< std::string, std::unique_ptr< domain::FunctionsOfTime::FunctionOfTime > > &functions_of_time) const
 
std::optional< std::array< double, Dim > > inverse (const std::array< double, Dim > &target_coords, double time, const std::unordered_map< std::string, std::unique_ptr< domain::FunctionsOfTime::FunctionOfTime > > &functions_of_time) const
 The inverse function is only callable with doubles because the inverse might fail if called for a point out of range, and it is unclear what should happen if the inverse were to succeed for some points in a DataVector but fail for other points.
 
template<typename T >
std::array< tt::remove_cvref_wrap_t< T >, Dim > frame_velocity (const std::array< T, Dim > &source_coords, double time, const std::unordered_map< std::string, std::unique_ptr< domain::FunctionsOfTime::FunctionOfTime > > &functions_of_time) const
 
template<typename T >
tnsr::Ij< tt::remove_cvref_wrap_t< T >, Dim, Frame::NoFramejacobian (const std::array< T, Dim > &source_coords, double time, const std::unordered_map< std::string, std::unique_ptr< domain::FunctionsOfTime::FunctionOfTime > > &functions_of_time) const
 
template<typename T >
tnsr::Ij< tt::remove_cvref_wrap_t< T >, Dim, Frame::NoFrameinv_jacobian (const std::array< T, Dim > &source_coords, double time, const std::unordered_map< std::string, std::unique_ptr< domain::FunctionsOfTime::FunctionOfTime > > &functions_of_time) const
 
void pup (PUP::er &p)
 
const std::unordered_set< std::string > & function_of_time_names () const
 

Static Public Member Functions

static bool is_identity ()
 

Static Public Attributes

static constexpr size_t dim = Dim
 

Friends

template<size_t LocalDim>
bool operator== (const Rotation< LocalDim > &lhs, const Rotation< LocalDim > &rhs)
 

Detailed Description

template<size_t Dim>
class domain::CoordinateMaps::TimeDependent::Rotation< Dim >

Time-dependent spatial rotation in two or three dimensions.

General Transformation

Let the source coordinates \( \vec{\xi} \) be mapped to coordinates \( \vec{x} \) using the transformation

\[ \vec{x} = R(t)\vec{\xi}, \]

where \( R(t) \) is a rotation matrix of proper dimensionality (defined below) and \( A\vec{v} \) is the standard matrix-vector multiplicaton. For 2D rotation, \( \vec{\xi} = \left(\xi, \eta\right) \) and \( \vec{x} = \left(x, y\right) \) while for 3D rotations \( \vec{\xi} = \left(\xi, \eta, \zeta\right) \) and \( \vec{x} = \left(x, y, z\right) \).

The inverse transformation is

\[ \vec{\xi} = R^T(t) \vec{x} \]

because the inverse of a rotation matrix is its transpose.

The frame velocity \( \vec{v} = d\vec{x}/dt \) is

\[ \vec{v} = \frac{d}{dt}\big( R(t) \big) \vec{\xi} \]

where \( d(R(t))/dt \) is the time derivative of the rotation matrix.

The components of the Jacobian \( \partial x^i/\partial\xi^j \) are trivially related to the components of the rotation matrix by

\[ \partial x^i/\partial\xi^j = R_{ij}, \]

and similarly the components of the inverse Jacobian \( \partial \xi^i/\partial x^j \) are

\[ \partial \xi^i/\partial x^j = R^{-1}_{ij} = R^T_{ij} = R_{ji}. \]

2D Rotation Matrix

The 2D rotaion matrix is defined in the usual way as

\[ R(t) = \begin{bmatrix} \cos(\theta(t)) & -\sin(\theta(t)) \\ \sin(\theta(t)) & \cos(\theta(t)) \\ \end{bmatrix}. \]

We associate the polar coordinates \( \left( \mathrm{P}, \Phi\right) \) with the unmapped coordinates \( \left(\xi, \eta\right) \) and the polar coordinates \( \left(r,\phi\right) \) with the mapped coordinates \( \left(x, y\right) \). We then have \( \phi = \Phi + \theta(t) \).

The derivative of the rotation matrix is then

\[ R(t) = \begin{bmatrix} -\omega(t) \sin(\theta(t)) & -\omega(t)\cos(\theta(t)) \\ \omega(t) \cos(\theta(t)) & -\omega(t)\sin(\theta(t)) \\ \end{bmatrix}. \]

where \( \omega(t) = d\theta(t)/dt \).

Note
This 2D rotation is assumed to be in the \( xy \)-plane (about the \( z \)-axis).

3D Rotation Matrix

For 3D rotations, we use quaternions to represent rotations about an arbitrary axis. We define a unit quaternion as

\[ \mathbf{q} = \left(q_0, q_1, q_2, q_3\right) = \left(q_0, \vec{q}\right) = \left(\cos(\frac{\theta(t)}{2}), \hat{n}\sin(\frac{\theta(t)}{2})\right) \]

where \( \hat{n} \) is our arbitrary rotation axis and \( \theta(t) \) is the angle rotated about that axis. A rotation in 3D is then defined as

\[ \mathbf{x} = \mathbf{q}\mathbf{\xi}\mathbf{q}^* \]

where \( \mathbf{q}^* = \left(\cos(\theta(t)/2), -\hat{n}\sin(\theta(t)/2)\right) \) and we promote the vectors to quaternions as \( \mathbf{x} = \left(0, \vec{x}\right) \) and \( \mathbf{\xi} = \left(0, \vec{\xi}\right) \). This will rotate the vector \( \vec{\xi} \) about \( \hat{n} \) by an angle \( \theta(t) \), transforming it into \( \vec{x} \).

We can represent this rotation using quaternions as a rotation matrix of the form

\[ R(t) = \begin{bmatrix} q_0^2 + q_1^2 - q_2^2 - q_3^2 & 2(q_1q_2 - q_0q_3) & 2(q_1q_3 + q_0q_2) \\ 2(q_1q_2 + q_0q_3) & q_0^2 + q_2^2 - q_1^2 - q_3^2 & 2(q_2q_3 - q_0q_1) \\ 2(q_1q_3 - q_0q_2) & 2(q_2q_3 + q_0q_1) & q_0^2 + q_3^2 - q_1^2 - q_2^2 \\ \end{bmatrix}. \]

The derivative of this rotation matrix can expressed in a similar form

\[ R(t) = \begin{bmatrix} 2(q_0\dot{q_0} + q_1\dot{q_1} - q_2\dot{q_2} - q_3\dot{q_3}) & 2(\dot{q_1}q_2 + q_1\dot{q_2} - \dot{q_0}q_3 - q_0\dot{q_3}) & 2(\dot{q_1}q_3 + q_1\dot{q_3} + \dot{q_0}q_2 + q_0\dot{q_2}) \\ 2(\dot{q_1}q_2 + q_1\dot{q_2} + \dot{q_0}q_3 + q_0\dot{q_3}) & 2(q_0\dot{q_0} + q_2\dot{q_2} - q_1\dot{q_1} - q_3\dot{q_3}) & 2(\dot{q_2}q_3 + q_2\dot{q_3} - \dot{q_0}q_1 - q_0\dot{q_1}) \\ 2(\dot{q_1}q_3 + q_1\dot{q_3} - \dot{q_0}q_2 - q_0\dot{q_2}) & 2(\dot{q_2}q_3 + q_2\dot{q_3} + \dot{q_0}q_1 + q_0\dot{q_1}) & 2(q_0\dot{q_0} + q_3\dot{q_3} - q_1\dot{q_1} - q_2\dot{q_2}) \\ \end{bmatrix}. \]

Note
If you choose \( \hat{n} = (0, 0, 1) \), this rotation will be equivalent to the 2D rotation.

The documentation for this class was generated from the following file: