Line data Source code
1 1 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : /// \file 5 : /// Defines the class CylindricalFlatEndcap. 6 : 7 : #pragma once 8 : 9 : #include <array> 10 : #include <cstddef> 11 : #include <limits> 12 : #include <optional> 13 : 14 : #include "DataStructures/Tensor/TypeAliases.hpp" 15 : #include "Domain/CoordinateMaps/FocallyLiftedFlatEndcap.hpp" 16 : #include "Domain/CoordinateMaps/FocallyLiftedMap.hpp" 17 : 18 : /// \cond 19 : namespace PUP { 20 : class er; 21 : } // namespace PUP 22 : /// \endcond 23 : 24 : namespace domain::CoordinateMaps { 25 : 26 : /*! 27 : * \ingroup CoordinateMapsGroup 28 : * 29 : * \brief Map from 3D unit right cylinder to a volume that connects 30 : * a portion of a circle to a portion of a spherical surface. 31 : * 32 : * \image html CylindricalFlatEndcap.svg "A cylinder maps to the shaded region." 33 : * 34 : * \details Consider a 2D circle in 3D space that is normal to the 35 : * \f$z\f$ axis and has (3D) center \f$C_1\f$ and radius \f$R_1\f$. 36 : * Also consider a sphere with center \f$C_2\f$, and radius \f$R_2\f$. 37 : * Also let there be a projection point \f$P\f$. 38 : * 39 : * CylindricalFlatEndcap maps a 3D unit right cylinder (with coordinates 40 : * \f$(\bar{x},\bar{y},\bar{z})\f$ such that \f$-1\leq\bar{z}\leq 1\f$ 41 : * and \f$\bar{x}^2+\bar{y}^2 \leq 1\f$) to the shaded area 42 : * in the figure above (with coordinates \f$(x,y,z)\f$). The "bottom" 43 : * of the cylinder \f$\bar{z}=-1\f$ is mapped to the interior of the 44 : * circle of radius \f$R_1\f$. Curves of constant 45 : * \f$(\bar{x},\bar{y})\f$ are mapped to portions of lines that pass 46 : * through \f$P\f$. Along each of these curves, \f$\bar{z}=-1\f$ is 47 : * mapped to a point on the circle and \f$\bar{z}=+1\f$ is mapped to a 48 : * point on the sphere. 49 : * 50 : * CylindricalFlatEndcap is intended to be composed with Wedge2D maps to 51 : * construct a portion of a cylindrical domain for a binary system. 52 : * 53 : * CylindricalFlatEndcap is described briefly in the Appendix of 54 : * \cite Buchman:2012dw. 55 : * CylindricalFlatEndcap is used to construct the blocks labeled 'MA 56 : * wedge' and 'MB wedge' in Figure 20 of that paper. 57 : * 58 : * CylindricalFlatEndcap is implemented using `FocallyLiftedMap` 59 : * and `FocallyLiftedInnerMaps::FlatEndcap`; see those classes for 60 : * details. 61 : * 62 : * ### Restrictions on map parameters. 63 : * 64 : * The following restrictions are made so that the map is not singular 65 : * or close to singular. It is possible to construct a valid map 66 : * without these assumptions, but the assumptions simplify the code and 67 : * avoid problematic edge cases, and the expected use cases obey 68 : * these restrictions. 69 : * 70 : * We demand that 71 : * - The plane containing the circle is below (i.e. at a smaller value 72 : * of \f$z\f$ than) the sphere, by an amount at least 5% of the sphere 73 : * radius \f$R_2\f$ but not more than 5 times the sphere radius \f$R_2\f$. 74 : * - \f$P\f$ is inside the sphere but not too close to its surface; 75 : * specifically, we demand that \f$|P-C_2|\leq 0.95 R_2\f$. 76 : * - The ratio \f$R_1/R_2\f$ is between 10 and 1/10, inclusive. 77 : * - The x and y components of \f$C_2-C_1\f$ both have magnitudes 78 : * smaller than or equal to \f$R_1+R_2\f$. 79 : * 80 : */ 81 1 : class CylindricalFlatEndcap { 82 : public: 83 0 : static constexpr size_t dim = 3; 84 0 : CylindricalFlatEndcap(const std::array<double, 3>& center_one, 85 : const std::array<double, 3>& center_two, 86 : const std::array<double, 3>& proj_center, 87 : double radius_one, double radius_two); 88 : 89 0 : CylindricalFlatEndcap() = default; 90 0 : ~CylindricalFlatEndcap() = default; 91 0 : CylindricalFlatEndcap(CylindricalFlatEndcap&&) = default; 92 0 : CylindricalFlatEndcap(const CylindricalFlatEndcap&) = default; 93 0 : CylindricalFlatEndcap& operator=(const CylindricalFlatEndcap&) = default; 94 0 : CylindricalFlatEndcap& operator=(CylindricalFlatEndcap&&) = default; 95 : 96 : template <typename T> 97 0 : std::array<T, 3> operator()(const std::array<T, 3>& source_coords) const; 98 : 99 0 : std::optional<std::array<double, 3>> inverse( 100 : const std::array<double, 3>& target_coords) const; 101 : 102 : template <typename T> 103 0 : tnsr::Ij<T, 3, Frame::NoFrame> jacobian( 104 : const std::array<T, 3>& source_coords) const; 105 : 106 : template <typename T> 107 0 : tnsr::Ij<T, 3, Frame::NoFrame> inv_jacobian( 108 : const std::array<T, 3>& source_coords) const; 109 : 110 : // NOLINTNEXTLINE(google-runtime-references) 111 0 : void pup(PUP::er& p); 112 : 113 0 : static bool is_identity() { return false; } 114 : 115 0 : static constexpr bool supports_hessian{false}; 116 : 117 : private: 118 0 : friend bool operator==(const CylindricalFlatEndcap& lhs, 119 : const CylindricalFlatEndcap& rhs); 120 0 : FocallyLiftedMap<FocallyLiftedInnerMaps::FlatEndcap> impl_; 121 : }; 122 0 : bool operator!=(const CylindricalFlatEndcap& lhs, 123 : const CylindricalFlatEndcap& rhs); 124 : 125 : } // namespace domain::CoordinateMaps