Line data Source code
1 1 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : /// \file 5 : /// Defines the class CylindricalFlatSide. 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/FocallyLiftedFlatSide.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 cylindrical shell to a volume that connects 30 : * a portion of an annulus to a portion of a spherical surface. 31 : * 32 : * \image html CylindricalFlatSide.svg "A cylinder maps to the shaded region." 33 : * 34 : * \details Consider a 2D annulus in 3D space that is normal to the 35 : * \f$z\f$ axis and has (3D) center \f$C_1\f$, inner radius 36 : * \f$R_\mathrm{in}\f$ and outer radius \f$R_\mathrm{out}\f$ 37 : * Also consider a sphere with center \f$C_2\f$, and radius \f$R_2\f$. 38 : * Also let there be a projection point \f$P\f$. 39 : * 40 : * CylindricalFlatSide maps a 3D unit right cylindrical shell (with 41 : * coordinates \f$(\bar{x},\bar{y},\bar{z})\f$ such that 42 : * \f$-1\leq\bar{z}\leq 1\f$ and \f$1 \leq \bar{x}^2+\bar{y}^2 \leq 43 : * 4\f$) to the shaded area in the figure above (with coordinates 44 : * \f$(x,y,z)\f$). The "bottom" of the cylinder \f$\bar{z}=-1\f$ is 45 : * mapped to the interior of the annulus with radii 46 : * \f$R_\mathrm{in}\f$ and \f$R_\mathrm{out}\f$. Curves of constant 47 : * \f$(\bar{x},\bar{y})\f$ are mapped to portions of lines that pass 48 : * through \f$P\f$. Along each of these curves, \f$\bar{z}=-1\f$ is 49 : * mapped to a point inside the annulus and \f$\bar{z}=+1\f$ is mapped to a 50 : * point on the sphere. 51 : * 52 : * CylindricalFlatSide is intended to be composed with Wedge2D maps to 53 : * construct a portion of a cylindrical domain for a binary system. 54 : * 55 : * CylindricalFlatSide is described briefly in the Appendix of 56 : * \cite Buchman:2012dw. 57 : * CylindricalFlatSide is used to construct the blocks labeled 'ME 58 : * cylinder' in Figure 20 of that paper. 59 : * 60 : * CylindricalFlatSide is implemented using `FocallyLiftedMap` 61 : * and `FocallyLiftedInnerMaps::FlatSide`; see those classes for 62 : * details. 63 : * 64 : * ### Restrictions on map parameters. 65 : * 66 : * We demand that: 67 : * - The sphere is at a larger value of \f$z\f$ (plus 5 68 : * percent of the sphere radius) than the plane containing the 69 : * annulus. 70 : * - The projection point \f$z_\mathrm{P}\f$ is 71 : * inside the sphere and more than 15 percent away from the boundary 72 : * of the sphere. 73 : * - The center of the annulus is contained in the circle that results from 74 : * projecting the sphere into the \f$xy\f$ plane. 75 : * - The outer radius of the annulus is larger than 5 percent of the distance 76 : * between the center of the annulus and the projection point. 77 : * - The inner radius of the annulus is less than 95 percent of the outer 78 : * radius, larger than 5 percent of the outer radius, and larger than one 79 : * percent of the distance between the center of the annulus and the 80 : * projection point. The last condition means that the angle subtended by 81 : * the inner radius with respect to the projection point is not too small. 82 : * 83 : * It is possible to construct a valid map without these assumptions, 84 : * but some of these assumptions simplify the code and others eliminate 85 : * edge cases where Jacobians become large or small. 86 : * 87 : */ 88 1 : class CylindricalFlatSide { 89 : public: 90 0 : static constexpr size_t dim = 3; 91 0 : CylindricalFlatSide(const std::array<double, 3>& center_one, 92 : const std::array<double, 3>& center_two, 93 : const std::array<double, 3>& proj_center, 94 : const double inner_radius, const double outer_radius, 95 : const double radius_two); 96 : 97 0 : CylindricalFlatSide() = default; 98 0 : ~CylindricalFlatSide() = default; 99 0 : CylindricalFlatSide(CylindricalFlatSide&&) = default; 100 0 : CylindricalFlatSide(const CylindricalFlatSide&) = default; 101 0 : CylindricalFlatSide& operator=(const CylindricalFlatSide&) = default; 102 0 : CylindricalFlatSide& operator=(CylindricalFlatSide&&) = default; 103 : 104 : template <typename T> 105 0 : std::array<T, 3> operator()(const std::array<T, 3>& source_coords) const; 106 : 107 0 : std::optional<std::array<double, 3>> inverse( 108 : const std::array<double, 3>& target_coords) const; 109 : 110 : template <typename T> 111 0 : tnsr::Ij<T, 3, Frame::NoFrame> jacobian( 112 : const std::array<T, 3>& source_coords) const; 113 : 114 : template <typename T> 115 0 : tnsr::Ij<T, 3, Frame::NoFrame> inv_jacobian( 116 : const std::array<T, 3>& source_coords) const; 117 : 118 : // NOLINTNEXTLINE(google-runtime-references) 119 0 : void pup(PUP::er& p); 120 : 121 0 : static bool is_identity() { return false; } 122 : 123 0 : static constexpr bool supports_hessian{false}; 124 : 125 : private: 126 0 : friend bool operator==(const CylindricalFlatSide& lhs, 127 : const CylindricalFlatSide& rhs); 128 0 : FocallyLiftedMap<FocallyLiftedInnerMaps::FlatSide> impl_; 129 : }; 130 0 : bool operator!=(const CylindricalFlatSide& lhs, const CylindricalFlatSide& rhs); 131 : 132 : } // namespace domain::CoordinateMaps