SpECTRE
v2024.09.29
|
Translation map defined by \(\vec{x} = \vec{\xi}+F(r)\vec{T}(t)\) where \(F(r)\) takes on different forms based on which constructor is used. More...
#include <Translation.hpp>
Public Member Functions | |
Translation (std::string function_of_time_name) | |
Translation (std::string function_of_time_name, double inner_radius, double outer_radius) | |
Translation (std::string function_of_time_name, std::unique_ptr< MathFunction< 1, Frame::Inertial > > radial_function, std::array< double, Dim > ¢er) | |
Translation (const Translation< Dim > &Translation_Map) | |
Translation (Translation &&)=default | |
Translation & | operator= (Translation &&)=default |
Translation & | operator= (const Translation &Translation_Map) |
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::NoFrame > | inv_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 |
template<typename T > | |
tnsr::Ij< tt::remove_cvref_wrap_t< T >, Dim, Frame::NoFrame > | 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 Translation< LocalDim > &lhs, const Translation< LocalDim > &rhs) |
Translation map defined by \(\vec{x} = \vec{\xi}+F(r)\vec{T}(t)\) where \(F(r)\) takes on different forms based on which constructor is used.
The map adds a translation to the coordinates \(\vec{\xi}\) based on what type of translation is needed. For the piecewise translation, a translation \(F(r)\vec{T}(t)\) is added to \(\vec{\xi}\) based on what region \(|\vec{\xi}|\) is in. For coordinates within the inner radius, \(F(r) = 1\) causing a uniform translation. Coordinates in between the inner and outer radius have a linear radial falloff applied to them. Coordinates beyond the outer radius have no translation applied to them \(F(r) = 0\). The piecewise translation assumes that the center of your map is at (0., 0., 0.). For the radial MathFunction translation, a radial translation \(F(r)\vec{T}(t)\) is added to the coordinates \(\vec{\xi}\), where \(\vec{T}(t)\) is a FunctionOfTime and \(F(r)\) is a 1D radial MathFunction. The radius of each point is found by subtracting the center map argument from the coordinates \(\vec{\xi}\) or the target coordinates \(\vec{\bar{\xi}}\). The Translation Map class is overloaded so that the user can choose between a piecewise translation, radial translation or a uniform translation based on their problem. If a radial dependence is not specified, this sets \(F(r) = 1\).
The piecewise translation translates the coordinates \(\vec{\xi}\) to the target coordinates \(\vec{\bar{\xi}}\) based on the region \(\vec{\xi}\) is in.
\begin{equation} \vec{\bar{\xi}} = \left\{\begin{array}{ll}\vec{\xi} + \vec{T}(t), & |\vec{\xi}| \leq R_{in}, \\ \vec{\xi} + wT(t), & R_{in} < |\vec{\xi}| < R_{out}, \\ \vec{\xi}, & |\vec{\xi}| \geq R_{out} \end{array}\right. \end{equation}
Where \(R_{in}\) is the inner radius, \(R_{out}\) is the outer radius, and \(w\) is the radial falloff factor found through
\begin{equation} w = \frac{R_{out} - |\vec{\xi}|}{R_{out} - R_{in}} \end{equation}
The radial MathFunction translation translates the coordinates \(\vec{\xi}\) to the target coordinates
\begin{equation}\vec{\bar{\xi}} = \vec{\xi} + F(r)\vec{T}(t) \end{equation}
If you only supply a FunctionOfTime to the constructor of this class, the radial function will be set to 1.0 causing a uniform translation for your coordinates. If a FunctionOfTime, MathFunction, and map center are passed in, the radius will be found through
\begin{equation} r = |\vec{\xi} - \vec{c}| \end{equation}
where r is the radius and \(\vec{c}\) is the center argument.
The piecewise inverse translates the coordinates \(\vec{\bar{\xi}}\) to the original coordinates based on what region \(\vec{\bar{\xi}}\) is in.
\begin{equation} \vec{\xi} = \left\{\begin{array}{ll}\vec{\bar{\xi}} - \vec{T}(t), & |\vec{\bar{\xi}}| \leq R_{in}, or, |\vec{\bar{\xi}} - T(t)| \leq R_{in}, \\ \vec{\bar{\xi}} - wT(t), & R_{in} < |\vec{\bar{\xi}}| < R_{out}, \\ \vec{\bar{\xi}}, & |\vec{\bar{\xi}}| \geq R_{out}\end{array}\right. \end{equation}
Where \(w\) is the radial falloff factor found through a quadratic solve of the form
\begin{equation} w^2(\vec{T}(t)^2 - (R_{out} - R_{in})^2) - 2w(\vec{T}(t)\vec{\bar{\xi}} - R_{out}(R_{out} - R_{in})) + \vec{\bar{\xi}}^2 - R_{out}^2 \end{equation}
The inverse map also assumes that if \(\vec{\bar{\xi}} - \vec{T}(t) \leq R_{in}\) then the translated point originally came from within the inner radius so it'll be translated back without a quadratic solve.
The radial MathFunction inverse translates the coordinates \(\vec{\bar{\xi}}\) to the original coordinates using
\begin{equation} \vec{\xi} = \vec{\bar{\xi}} - F(r)\vec{T}(t) \end{equation}
where \(r^2\) is found as the root of
\begin{equation} r^2 = \Big(\vec{\bar{\xi}} - \vec{c} - F(r) \vec{T}(t)\Big)^2. \end{equation}
For the piecewise translation, the frame velocity is found through
\begin{equation} \vec{v} = \left\{\begin{array}{ll}\frac{\vec{dT}(t)}{dt}, & |\vec{\xi}| \leq R_{in}, \\ w\frac{\vec{dT}(t)}{dt}, & R_{in} < |\vec{\xi}| < R_{out}, \\ 0, & |\vec{\xi}| \geq R_{out} \end{array}\right. \end{equation}
For the radial MathFunction translation, the frame velocity is found through
\begin{equation} \vec{v} = \frac{\vec{dT}(t)}{dt} F(r) \end{equation}
where \(\frac{\vec{dT}(t)}{dt}\) is the first derivative of the FunctionOfTime.
For the piecewise translation, the jacobian is computed based on what region the coordinates \(\vec{\xi}\) is in.
\begin{equation} {J^{i}}_{j} = \frac{dw}{dr} T(t)^i \frac{\xi_j}{r}, R_{in} < |\vec{\bar{\xi}}| < R_{out} \end{equation}
otherwise, it will return the identity matrix.
For the radial MathFunction translation, the jacobian is computed through the first derivative when the radius is bigger than 1.e-13:
\begin{equation} {J^{i}}_{j} = \frac{dF(r)}{dr} T(t)^i \frac{(\xi_j - c_j)}{r} \end{equation}
Where \(\frac{dF(r)}{dr}\) is the first derivative of the MathFunction, \(\vec{\xi_j}\) is the source coordinates, \(\vec{c}\) is the center of your map, and r is the radius.
At a radius smaller than 1e-13, we ASSERT that the radial MathFunction is smooth \(\frac{dF(r)}{dr} \approx 0\), so return the identity matrix.
The inverse jacobian is computed numerically by inverting the jacobian.