SpECTRE
v2024.12.16
|
Map from 3D unit right cylinder to a volume that connects portions of two spherical surfaces. More...
#include <CylindricalEndcap.hpp>
Public Member Functions | |
CylindricalEndcap (const std::array< double, 3 > ¢er_one, const std::array< double, 3 > ¢er_two, const std::array< double, 3 > &proj_center, double radius_one, double radius_two, double z_plane) | |
CylindricalEndcap (CylindricalEndcap &&)=default | |
CylindricalEndcap (const CylindricalEndcap &)=default | |
CylindricalEndcap & | operator= (const CylindricalEndcap &)=default |
CylindricalEndcap & | operator= (CylindricalEndcap &&)=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 CylindricalEndcap &lhs, const CylindricalEndcap &rhs) |
Map from 3D unit right cylinder to a volume that connects portions of two spherical surfaces.
Consider two spheres with centers \(C_1\) and \(C_2\), and radii \(R_1\) and \(R_2\). Let sphere 1 be intersected by a plane normal to the \(z\) axis and located at \(z = z_\mathrm{P}\). Also let there be a projection point \(P\).
CylindricalEndcap maps a 3D unit right cylinder (with coordinates \((\bar{x},\bar{y},\bar{z})\) such that \(-1\leq\bar{z}\leq 1\) and \(\bar{x}^2+\bar{y}^2 \leq 1\)) to the shaded area in the figure above (with coordinates \((x,y,z)\)). The "bottom" of the cylinder \(\bar{z}=-1\) is mapped to the portion of sphere 1 that has \(z \geq z_\mathrm{P}\). Curves of constant \((\bar{x},\bar{y})\) are mapped to portions of lines that pass through \(P\). Along each of these curves, \(\bar{z}=-1\) is mapped to a point on sphere 1 and \(\bar{z}=+1\) is mapped to a point on sphere 2.
Note that Sphere 1 and Sphere 2 are not equivalent, because the mapped portion of Sphere 1 is bounded by a plane of constant \(z\) but the mapped portion of Sphere 2 is not (except for special choices of \(C_1\), \(C_2\), and \(P\)).
CylindricalEndcap is intended to be composed with Wedge<2>
maps to construct a portion of a cylindrical domain for a binary system.
CylindricalEndcap is described briefly in the Appendix of [32]. CylindricalEndcap is used to construct the blocks labeled 'CA wedge', 'EA wedge', 'CB wedge', 'EE wedge', and 'EB wedge' in Figure 20 of that paper. Note that 'CA wedge', 'CB wedge', and 'EE wedge' have Sphere 1 contained in Sphere 2, and 'EA wedge' and 'EB wedge' have Sphere 2 contained in Sphere 1.
CylindricalEndcap is implemented using FocallyLiftedMap
and FocallyLiftedInnerMaps::Endcap
; see those classes for details.
We demand that either Sphere 1 is fully contained inside Sphere 2, or that Sphere 2 is fully contained inside Sphere 1. It is possible to construct a valid map without this assumption, but the assumption simplifies the code, and the expected use cases obey this restriction.
We also demand that \(z_\mathrm{P} > C_1^2\), that is, the plane in the above and below figures lies to the right of \(C_1^2\). This restriction not strictly necessary but is made for simplicity.
The map is invertible only for some choices of the projection point \(P\). Given the above restrictions, the allowed values of \(P\) are illustrated by the following diagram:
The plane \(z=z_\mathrm{P}\) intersects sphere 1 on a circle. The cone with apex \(C_1\) that intersects that circle has opening angle \(2\theta\) as shown in the above figure. Construct another cone, the "invertibility cone", with apex \(S\) chosen such that the two cones intersect at right angles on the circle; thus the opening angle of the invertibility cone is \(\pi-2\theta\). A necessary condition for invertibility is that the projection point \(P\) lies inside the invertibility cone, but not between \(S\) and sphere 1. (If \(P\) does not obey this condition, then from the diagram one can find at least one line through \(P\) that twice intersects the surface of sphere 1 with \(z>z_\mathrm{P}\); the inverse map is thus double-valued at those intersection points.) Placing the projection point \(P\) to the right of \(S\) (but inside the invertibility cone) is ok for invertibility.
In addition to invertibility and the two additional restrictions already mentioned above, we demand a few more restrictions on the map parameters to simplify the logic for the expected use cases and to ensure that jacobians do not get too large. The numbers in the restrictions below were chosen empirically so that the unit tests pass with errors less than 100 times machine roundoff; we do not expect to run into these restrictions in normal usage. We demand: