SpECTRE
v2025.01.30
|
Map from
#include <FocallyLiftedMap.hpp>
Public Member Functions | |
FocallyLiftedMap (const std::array< double, 3 > ¢er, const std::array< double, 3 > &proj_center, double radius, bool source_is_between_focus_and_target, InnerMap inner_map) | |
FocallyLiftedMap (FocallyLiftedMap &&)=default | |
FocallyLiftedMap (const FocallyLiftedMap &)=default | |
FocallyLiftedMap & | operator= (const FocallyLiftedMap &)=default |
FocallyLiftedMap & | operator= (FocallyLiftedMap &&)=default |
template<typename T > | |
std::array< tt::remove_cvref_wrap_t< T >, 3 > | operator() (const std::array< T, 3 > &source_coords) const |
std::optional< std::array< double, 3 > > | inverse (const std::array< double, 3 > &target_coords) 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 > | |
tnsr::Ij< tt::remove_cvref_wrap_t< T >, 3, Frame::NoFrame > | jacobian (const std::array< T, 3 > &source_coords) const |
template<typename T > | |
tnsr::Ij< tt::remove_cvref_wrap_t< T >, 3, Frame::NoFrame > | inv_jacobian (const std::array< T, 3 > &source_coords) 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 FocallyLiftedMap< InnerMap > &lhs, const FocallyLiftedMap< InnerMap > &rhs) |
Map from
We are given the radius InnerMap
template parameter, we are given the functions
The above figure is a 2D representation of the focally lifted map, where the shaded region in
The input coordinates are labeled
Now let
where
where
The quadratic equation, Eq. (2), takes the usual form
Now assume that
Note that classes using FocallyLiftedMap will place restrictions on
Also note that the quadratic Eq. (2) typically has more than one root, corresponding to two intersections of the sphere. The boolean parameter source_is_between_focus_and_target
that is passed into the constructor of FocallyLiftedMap
is used to choose the appropriate root, or to error if a suitable root is not found. source_is_between_focus_and_target
should be true if the source point lies between the projection point source_is_between_focus_and_target
is known only by each particular CoordinateMap
that uses FocallyLiftedMap
.
Differentiating Eq. (1) above yields
and differentiating Eq. (2) and then inserting Eq. (1) yields
The Jacobian can be found by differentiating Eq. (3) above and using the chain rule, recognizing that
where in the last line we have substituted Eq. (4).
The class defined by the InnerMap
template parameter provides the function deriv_sigma
, which returns jacobian
, which returns
Given
We first find the coordinates
where InnerMap
template parameter. InnerMap
provides a function lambda_tilde
that takes std::optional
if the appropriate
Now consider the coordinates
where
Eq. (9) is a quadratic equation that takes the usual form
Note that we don't actually need to compute
The denominator of Eq. (10) is nonzero for nonsingular maps: From Eqs. (7) and (8),
Once we have InnerMap
. The inverse
function of InnerMap
takes std::optional
if
The inverse function described above will sometimes have errors that are noticeably larger than roundoff. Therefore we apply a single Newton-Raphson iteration to refine the result of the inverse map: Suppose we are given
where
We write the inverse Jacobian as
where we have recognized that
We now evaluate Eq. (12). The InnerMap
class provides a function inv_jacobian
that returns dxbar_dsigma
that returns
where deriv_lambda_tilde
function of InnerMap
. Note that for nonsingular maps there is no worry that
To evaluate the remaining unknown factor in Eq. (12),
Differentiating this expression yields
where the second factor in the first term can be evaluated using Eq. (5), the third factor in the first term can be evaluated using Eq. (13), and the second factor in the second term is provided by InnerMap
s function deriv_lambda_tilde
.