Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstddef>
7 :
8 : #include "DataStructures/DataBox/Tag.hpp"
9 : #include "DataStructures/Tensor/Metafunctions.hpp"
10 : #include "DataStructures/Tensor/TypeAliases.hpp"
11 : #include "Utilities/Gsl.hpp"
12 :
13 : /// \cond
14 : class DataVector;
15 : /// \endcond
16 :
17 : /// Holds functions related to transforming between frames.
18 1 : namespace transform {
19 : /// @{
20 : /*!
21 : * \ingroup GeneralRelativityGroup
22 : * Transforms tensor to different frame.
23 : *
24 : * The formula for transforming \f$T_{ij}\f$ is
25 : * \f{align}
26 : * T_{\bar{\imath}\bar{\jmath}} &= T_{ij}
27 : * \frac{\partial x^i}{\partial x^{\bar{\imath}}}
28 : * \frac{\partial x^j}{\partial x^{\bar{\jmath}}}
29 : * \f}
30 : * where \f$x^i\f$ are the source coordinates and
31 : * \f$x^{\bar{\imath}}\f$ are the destination coordinates.
32 : *
33 : * Note that `Jacobian<DestFrame,SrcFrame>` is the same type as
34 : * `InverseJacobian<SrcFrame,DestFrame>` and represents
35 : * \f$\partial x^i/\partial x^{\bar{\jmath}}\f$.
36 : */
37 : template <typename DataType, size_t VolumeDim, typename SrcFrame,
38 : typename DestFrame>
39 1 : void to_different_frame(
40 : const gsl::not_null<tnsr::ii<DataType, VolumeDim, DestFrame>*> dest,
41 : const tnsr::ii<DataType, VolumeDim, SrcFrame>& src,
42 : const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian);
43 :
44 : template <typename DataType, size_t VolumeDim, typename SrcFrame,
45 : typename DestFrame>
46 1 : auto to_different_frame(
47 : const tnsr::ii<DataType, VolumeDim, SrcFrame>& src,
48 : const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian)
49 : -> tnsr::ii<DataType, VolumeDim, DestFrame>;
50 : /// @}
51 :
52 : /// @{
53 : /*!
54 : * \ingroup GeneralRelativityGroup
55 : * \brief Transforms a tensor to a different frame.
56 : *
57 : * The tensor being transformed is always assumed to have density zero. In
58 : * particular `Scalar` is assumed to be invariant under transformations.
59 : *
60 : * \warning The \p jacobian argument is the derivative of the *source*
61 : * coordinates with respect to the *destination* coordinates.
62 : */
63 : template <typename DataType, size_t VolumeDim, typename SrcFrame,
64 : typename DestFrame>
65 1 : void to_different_frame(
66 : const gsl::not_null<Scalar<DataType>*> dest, const Scalar<DataType>& src,
67 : const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
68 : const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
69 : inv_jacobian);
70 :
71 : template <typename DataType, size_t VolumeDim, typename SrcFrame,
72 : typename DestFrame>
73 1 : auto to_different_frame(
74 : Scalar<DataType> src,
75 : const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
76 : const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
77 : inv_jacobian) -> Scalar<DataType>;
78 :
79 : template <typename DataType, size_t VolumeDim, typename SrcFrame,
80 : typename DestFrame>
81 1 : void to_different_frame(
82 : const gsl::not_null<tnsr::I<DataType, VolumeDim, DestFrame>*> dest,
83 : const tnsr::I<DataType, VolumeDim, SrcFrame>& src,
84 : const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
85 : const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
86 : inv_jacobian);
87 :
88 : template <typename DataType, size_t VolumeDim, typename SrcFrame,
89 : typename DestFrame>
90 1 : auto to_different_frame(
91 : const tnsr::I<DataType, VolumeDim, SrcFrame>& src,
92 : const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
93 : const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
94 : inv_jacobian) -> tnsr::I<DataType, VolumeDim, DestFrame>;
95 :
96 : template <typename DataType, size_t VolumeDim, typename SrcFrame,
97 : typename DestFrame>
98 : void to_different_frame(
99 : const gsl::not_null<tnsr::i<DataType, VolumeDim, DestFrame>*> dest,
100 : const tnsr::i<DataType, VolumeDim, SrcFrame>& src,
101 : const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
102 : const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
103 : inv_jacobian);
104 :
105 : template <typename DataType, size_t VolumeDim, typename SrcFrame,
106 : typename DestFrame>
107 : auto to_different_frame(
108 : const tnsr::i<DataType, VolumeDim, SrcFrame>& src,
109 : const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
110 : const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
111 : inv_jacobian) -> tnsr::i<DataType, VolumeDim, DestFrame>;
112 :
113 : template <typename DataType, size_t VolumeDim, typename SrcFrame,
114 : typename DestFrame>
115 : void to_different_frame(
116 : const gsl::not_null<tnsr::iJ<DataType, VolumeDim, DestFrame>*> dest,
117 : const tnsr::iJ<DataType, VolumeDim, SrcFrame>& src,
118 : const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
119 : const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
120 : inv_jacobian);
121 :
122 : template <typename DataType, size_t VolumeDim, typename SrcFrame,
123 : typename DestFrame>
124 : auto to_different_frame(
125 : const tnsr::iJ<DataType, VolumeDim, SrcFrame>& src,
126 : const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
127 : const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
128 : inv_jacobian) -> tnsr::iJ<DataType, VolumeDim, DestFrame>;
129 :
130 : template <typename DataType, size_t VolumeDim, typename SrcFrame,
131 : typename DestFrame>
132 : void to_different_frame(
133 : const gsl::not_null<tnsr::ii<DataType, VolumeDim, DestFrame>*> dest,
134 : const tnsr::ii<DataType, VolumeDim, SrcFrame>& src,
135 : const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
136 : const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
137 : inv_jacobian);
138 :
139 : template <typename DataType, size_t VolumeDim, typename SrcFrame,
140 : typename DestFrame>
141 : auto to_different_frame(
142 : const tnsr::ii<DataType, VolumeDim, SrcFrame>& src,
143 : const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
144 : const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
145 : inv_jacobian) -> tnsr::ii<DataType, VolumeDim, DestFrame>;
146 :
147 : template <typename DataType, size_t VolumeDim, typename SrcFrame,
148 : typename DestFrame>
149 : void to_different_frame(
150 : const gsl::not_null<tnsr::II<DataType, VolumeDim, DestFrame>*> dest,
151 : const tnsr::II<DataType, VolumeDim, SrcFrame>& src,
152 : const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
153 : const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
154 : inv_jacobian);
155 :
156 : template <typename DataType, size_t VolumeDim, typename SrcFrame,
157 : typename DestFrame>
158 : auto to_different_frame(
159 : const tnsr::II<DataType, VolumeDim, SrcFrame>& src,
160 : const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
161 : const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
162 : inv_jacobian) -> tnsr::II<DataType, VolumeDim, DestFrame>;
163 :
164 : template <typename DataType, size_t VolumeDim, typename SrcFrame,
165 : typename DestFrame>
166 : void to_different_frame(
167 : const gsl::not_null<tnsr::ijj<DataType, VolumeDim, DestFrame>*> dest,
168 : const tnsr::ijj<DataType, VolumeDim, SrcFrame>& src,
169 : const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
170 : const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
171 : inv_jacobian);
172 :
173 : template <typename DataType, size_t VolumeDim, typename SrcFrame,
174 : typename DestFrame>
175 : auto to_different_frame(
176 : const tnsr::ijj<DataType, VolumeDim, SrcFrame>& src,
177 : const Jacobian<DataType, VolumeDim, DestFrame, SrcFrame>& jacobian,
178 : const InverseJacobian<DataType, VolumeDim, DestFrame, SrcFrame>&
179 : inv_jacobian) -> tnsr::ijj<DataType, VolumeDim, DestFrame>;
180 : /// @}
181 :
182 : /// @{
183 : /*!
184 : * \ingroup GeneralRelativityGroup
185 : * Transforms only the first index to different frame.
186 : *
187 : * ## Examples for transforming some tensors
188 : *
189 : * ### Flux vector to logical coordinates
190 : *
191 : * A common example is taking the divergence of a flux vector $F^i$, where the
192 : * index $i$ is in inertial coordinates $x^i$ and the divergence is taken in
193 : * logical coordinates $\xi^\hat{i}$. So to transform the flux vector to logical
194 : * coordinates before taking the divergence we do this:
195 : *
196 : * \f{align}
197 : * F^\hat{i} &= F^i \frac{\partial x^\hat{i}}{\partial x^i}
198 : * \f}
199 : *
200 : * Here, $\frac{\partial x^\hat{i}}{\partial x^i}$ is the inverse Jacobian (see
201 : * definitions in TypeAliases.hpp).
202 : *
203 : * Currently, this function is tested for any tensor with a first upper spatial
204 : * index. It can be extended/generalized to other tensor types if needed.
205 : */
206 : template <typename ResultTensor, typename InputTensor, typename DataType,
207 : size_t Dim, typename SourceFrame, typename TargetFrame>
208 1 : void first_index_to_different_frame(
209 : gsl::not_null<ResultTensor*> result, const InputTensor& input,
210 : const InverseJacobian<DataType, Dim, SourceFrame, TargetFrame>&
211 : inv_jacobian);
212 :
213 : template <typename InputTensor, typename DataType, size_t Dim,
214 : typename SourceFrame, typename TargetFrame,
215 : typename ResultTensor = TensorMetafunctions::prepend_spatial_index<
216 : TensorMetafunctions::remove_first_index<InputTensor>, Dim,
217 : UpLo::Up, SourceFrame>>
218 1 : ResultTensor first_index_to_different_frame(
219 : const InputTensor& input,
220 : const InverseJacobian<DataType, Dim, SourceFrame, TargetFrame>&
221 : inv_jacobian);
222 : /// @}
223 : } // namespace transform
|