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);
|