SpECTRE
v2023.01.13
|
Distorts a distribution of points radially according to a spherical harmonic expansion while preserving angles. More...
#include <Shape.hpp>
Public Types | |
using | FunctionsOfTimeMap = std::unordered_map< std::string, std::unique_ptr< domain::FunctionsOfTime::FunctionOfTime > > |
Public Member Functions | |
Shape (const std::array< double, 3 > ¢er, size_t l_max, size_t m_max, std::unique_ptr< ShapeMapTransitionFunctions::ShapeMapTransitionFunction > transition_func, std::string function_of_time_name) | |
Shape (Shape &&)=default | |
Shape & | operator= (Shape &&)=default |
Shape (const Shape &rhs) | |
Shape & | operator= (const Shape &rhs) |
template<typename T > | |
std::array< tt::remove_cvref_wrap_t< T >, 3 > | operator() (const std::array< T, 3 > &source_coords, double time, const FunctionsOfTimeMap &functions_of_time) const |
std::optional< std::array< double, 3 > > | inverse (const std::array< double, 3 > &target_coords, double time, const FunctionsOfTimeMap &functions_of_time) const |
template<typename T > | |
std::array< tt::remove_cvref_wrap_t< T >, 3 > | frame_velocity (const std::array< T, 3 > &source_coords, double time, const FunctionsOfTimeMap &functions_of_time) const |
template<typename T > | |
tnsr::Ij< tt::remove_cvref_wrap_t< T >, 3, Frame::NoFrame > | jacobian (const std::array< T, 3 > &source_coords, double time, const FunctionsOfTimeMap &functions_of_time) const |
template<typename T > | |
tnsr::Ij< tt::remove_cvref_wrap_t< T >, 3, Frame::NoFrame > | inv_jacobian (const std::array< T, 3 > &source_coords, double time, const FunctionsOfTimeMap &functions_of_time) const |
void | pup (PUP::er &p) |
Static Public Member Functions | |
static bool | is_identity () |
Static Public Attributes | |
static constexpr size_t | dim = 3 |
Friends | |
bool | operator== (const Shape &lhs, const Shape &rhs) |
Distorts a distribution of points radially according to a spherical harmonic expansion while preserving angles.
Given a point with cartesian coordinates \(\xi^i\), let the polar coordinates \((r, \theta, \phi)\) with respect to a center \(x_c^i\) be defined in the usual way:
\begin{align} \xi^0 - x_c^0 &= r sin(\theta) cos(\phi)\\ \xi^1 - x_c^1 &= r sin(\theta) sin(\phi)\\ \xi^2 - x_c^2 &= r cos(\theta) \end{align}
The shape map distorts the distance \(r\) between the point and the center while leaving the angles \(\theta\), \(\phi\) between them preserved by applying a spherical harmonic expansion with time-dependent coefficients \(\lambda_{lm}(t)\). An additional domain-dependent transition function \(f(r, \theta, \phi)\) ensures that the distortion falls off correctly to zero at the boundary of the domain. The shape map maps the unmapped coordinates \(\xi^i\) to coordinates \(x^i\):
\begin{equation} x^i = \xi^i - (\xi^i - x_c^i) f(r, \theta, \phi) \sum_{lm} \lambda_{lm}(t)Y_{lm}(\theta, \phi). \end{equation}
The inverse map is given by:
\begin{equation} \xi^i = x_c^i + (x^i-x_c^i)*(r/\tilde{r}), \end{equation}
where \(\tilde{r}\) is the radius of \(\xi\), calculated by the transition map. For more details, see ShapeMapTransitionFunction::original_radius_over_radius .
The frame velocity \(v^i\ = dx^i / dt\) is calculated trivially:
\begin{equation} v^i = - (\xi^i - x_c^i) f(r, \theta, \phi) \sum_{lm} \dot{\lambda}_{lm}(t)Y_{lm}(\theta, \phi). \end{equation}
The Jacobian is given by:
\begin{equation} \frac{\partial}{\partial \xi^j} x^i = \delta_j^i \left( 1 - f(r, \theta, \phi) \sum_{lm} \lambda_{lm}(t)Y_{lm}(\theta, \phi)\right) + (\xi^i - x_c^i) \left(\frac{\partial}{\partial \xi^j} f(r, \theta, \phi) \sum_{lm} \lambda_{lm}(t)Y_{lm}(\theta, \phi) + f(r, \theta, \phi) \sum_{lm} \lambda_{lm}(t) \frac{\partial}{\partial \xi^j} Y_{lm}(\theta, \phi) \right). \end{equation}
The inverse Jacobian is computed by numerically inverting the Jacobian.
For future optimization, the interpolation_info
objects calculated in all functions of this class could be cached. Since every element should evaluate the same grid coordinates most time steps, this might greatly decrease computation. Every element has their own clone of the shape map so the caching could be done with member variables. Care must be taken that jacobian
currently calculates the interpolation_info
with an order higher.