Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <memory> 7 : #include <string> 8 : #include <unordered_map> 9 : 10 : #include "DataStructures/Tensor/TypeAliases.hpp" 11 : 12 : /// \cond 13 : namespace ylm { 14 : template <typename Frame> 15 : class Strahlkorper; 16 : } // namespace ylm 17 : template <size_t Dim> 18 : class Domain; 19 : namespace domain::FunctionsOfTime { 20 : class FunctionOfTime; 21 : } // namespace domain::FunctionsOfTime 22 : namespace gsl { 23 : template <typename T> 24 : class not_null; 25 : } // namespace gsl 26 : /// \endcond 27 : 28 : /// \brief Transforms a Strahlkorper from SrcFrame to DestFrame. 29 : /// 30 : /// The destination Strahlkorper has the same l_max() and m_max() as the 31 : /// source Strahlkorper. 32 : /// 33 : /// \note Because the Blocks inside the Domain allow access to 34 : /// maps only between a selected subset of frames, we cannot use 35 : /// strahlkorper_in_different_frame to map between arbitrary frames; 36 : /// allowing strahlkorper_in_different_frame to work on more frames 37 : /// requires adding member functions to Block. 38 : /// 39 : /// \note strahlkorper_in_different_frame is currently instantiated 40 : /// only for i) SrcFrame=Grid and DestFrame=Inertial and ii) SrcFrame=Inertial 41 : /// and DestFrame=Distorted (necessary for initializing a binary-black-hole 42 : /// ringdown). In particular, we intentionally do not instantiate 43 : /// strahlkorper_in_different_frame for SrcFrame=Grid and DestFrame=Distorted, 44 : /// because our Grid->Distorted maps preserve centers and angles, so for 45 : /// Grid->Distorted one should use 46 : /// strahlkorper_in_different_frame_aligned because it is more 47 : /// efficient. 48 : template <typename SrcFrame, typename DestFrame> 49 1 : void strahlkorper_in_different_frame( 50 : gsl::not_null<ylm::Strahlkorper<DestFrame>*> dest_strahlkorper, 51 : const ylm::Strahlkorper<SrcFrame>& src_strahlkorper, 52 : const Domain<3>& domain, 53 : const std::unordered_map< 54 : std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>& 55 : functions_of_time, 56 : double time); 57 : 58 : /// \brief Transforms a Strahlkorper from SrcFrame to DestFrame, for easy maps. 59 : /// 60 : /// This is a simplified version of strahlkorper_in_different_frame 61 : /// with the following two assumptions: First, the map leaves the 62 : /// center of the Strahlkorper invariant. Second, for every point on 63 : /// the Strahlkorper, the map leaves the angles about the center 64 : /// (i.e. the quantity 65 : /// \f$(x^i-c^i)/\sqrt{(x^0-c^0)^2+(x^1-c^1)^2+(x^2-c^2)^2}\f$) 66 : /// invariant. If those assumptions are not satisfied, then 67 : /// strahlkorper_in_different_frame_aligned will give the wrong answer 68 : /// and you must use strahlkorper_in_different_frame. Those 69 : /// assumptions are satisfied for the shape and size maps but not for 70 : /// general maps. 71 : /// 72 : /// \note strahlkorper_in_different_frame_aligned is instantiated only 73 : /// for SrcFrame=Grid and DestFrame=Distorted or Inertial. This 74 : /// doesn't mean that strahlkorper_in_different_frame_aligned is 75 : /// always correct for Grid->Inertial; the correctness depends on 76 : /// whether the Grid->Inertial map satisfies the above assumptions, 77 : /// which it might for simple cases (like single BHs) but it won't for 78 : /// more complicated cases (like BBHs). To add different frames to 79 : /// strahlkorper_in_different_frame_aligned, one must add `if 80 : /// constexpr`s to call the appropriate member functions of Block. 81 : template <typename SrcFrame, typename DestFrame> 82 1 : void strahlkorper_in_different_frame_aligned( 83 : gsl::not_null<ylm::Strahlkorper<DestFrame>*> dest_strahlkorper, 84 : const ylm::Strahlkorper<SrcFrame>& src_strahlkorper, 85 : const Domain<3>& domain, 86 : const std::unordered_map< 87 : std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>& 88 : functions_of_time, 89 : double time); 90 : 91 : /// \brief Maps (cartesian) collocation points of a Strahlkorper to 92 : /// a different frame. 93 : /// 94 : /// If SrcFrame is Frame::Distorted, strahlkorper_coords_in_different_frame 95 : /// will fail if src_strahlkorper intersects a Block that lacks a distorted 96 : /// frame. Note that if such a Strahlkorper intersects 97 : /// such a Block, we have worse problems anyway (e.g. jacobians will usually 98 : /// be discontinuous at the boundaries of such a Block, and attempting to 99 : /// find such a Strahlkorper with an apparent-horizon finder will probably 100 : /// fail). 101 : /// 102 : /// Note that because the Blocks inside the Domain allow access to 103 : /// maps only between a selected subset of frames, we cannot use 104 : /// strahlkorper_in_different_frame to map between arbitrary frames; 105 : /// allowing strahlkorper_coords_in_different_frame to work on more frames 106 : /// requires adding member functions to Block. 107 : template <typename SrcFrame, typename DestFrame> 108 1 : void strahlkorper_coords_in_different_frame( 109 : gsl::not_null<tnsr::I<DataVector, 3, DestFrame>*> dest_cartesian_coords, 110 : const ylm::Strahlkorper<SrcFrame>& src_strahlkorper, 111 : const Domain<3>& domain, 112 : const std::unordered_map< 113 : std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>& 114 : functions_of_time, 115 : double time);