Line data Source code
1 1 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : ///\file
5 : /// Defines functions to calculate Christoffel symbols
6 :
7 : #pragma once
8 :
9 : #include <cstddef>
10 :
11 : #include "DataStructures/DataBox/Tag.hpp"
12 : #include "DataStructures/Tensor/EagerMath/RaiseOrLowerIndex.hpp"
13 : #include "DataStructures/Tensor/EagerMath/Trace.hpp"
14 : #include "DataStructures/Tensor/IndexType.hpp"
15 : #include "DataStructures/Tensor/TypeAliases.hpp"
16 : #include "Evolution/Systems/GeneralizedHarmonic/Tags.hpp"
17 : #include "NumericalAlgorithms/LinearOperators/PartialDerivatives.hpp"
18 : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
19 :
20 : /// \cond
21 : namespace gsl {
22 : template <class>
23 : class not_null;
24 : } // namespace gsl
25 : /// \endcond
26 :
27 : namespace gr {
28 : /// @{
29 : /*!
30 : * \ingroup GeneralRelativityGroup
31 : * \brief Computes Christoffel symbol of the first kind from derivative of
32 : * metric
33 : *
34 : * \details Computes Christoffel symbol \f$\Gamma_{abc}\f$ as:
35 : * \f$ \Gamma_{cab} = \frac{1}{2} ( \partial_a g_{bc} + \partial_b g_{ac}
36 : * - \partial_c g_{ab}) \f$
37 : * where \f$g_{bc}\f$ is either a spatial or spacetime metric
38 : */
39 : template <size_t SpatialDim, typename Frame, IndexType Index, typename DataType>
40 1 : void christoffel_first_kind(
41 : gsl::not_null<tnsr::abb<DataType, SpatialDim, Frame, Index>*> christoffel,
42 : const tnsr::abb<DataType, SpatialDim, Frame, Index>& d_metric);
43 :
44 : template <size_t SpatialDim, typename Frame, IndexType Index, typename DataType>
45 1 : tnsr::abb<DataType, SpatialDim, Frame, Index> christoffel_first_kind(
46 : const tnsr::abb<DataType, SpatialDim, Frame, Index>& d_metric);
47 : /// @}
48 :
49 : /// @{
50 : /*!
51 : * \ingroup GeneralRelativityGroup
52 : * \brief Computes Christoffel symbol of the second kind from derivative of
53 : * metric and the inverse metric.
54 : *
55 : * \details Computes Christoffel symbol \f$\Gamma^a_{bc}\f$ as:
56 : * \f$ \Gamma^d_{ab} = \frac{1}{2} g^{cd} (\partial_a g_{bc} + \partial_b g_{ac}
57 : * - \partial_c g_{ab}) \f$
58 : * where \f$g_{bc}\f$ is either a spatial or spacetime metric.
59 : *
60 : * Avoids the extra memory allocation that occurs by computing the
61 : * Christoffel symbol of the first kind and then raising the index.
62 : */
63 : template <size_t SpatialDim, typename Frame, IndexType Index, typename DataType>
64 1 : void christoffel_second_kind(
65 : const gsl::not_null<tnsr::Abb<DataType, SpatialDim, Frame, Index>*>
66 : christoffel,
67 : const tnsr::abb<DataType, SpatialDim, Frame, Index>& d_metric,
68 : const tnsr::AA<DataType, SpatialDim, Frame, Index>& inverse_metric);
69 :
70 : template <size_t SpatialDim, typename Frame, IndexType Index, typename DataType>
71 1 : auto christoffel_second_kind(
72 : const tnsr::abb<DataType, SpatialDim, Frame, Index>& d_metric,
73 : const tnsr::AA<DataType, SpatialDim, Frame, Index>& inverse_metric)
74 : -> tnsr::Abb<DataType, SpatialDim, Frame, Index>;
75 : /// @}
76 :
77 0 : namespace Tags {
78 : /// Compute item for spatial Christoffel symbols of the first kind
79 : /// \f$\Gamma_{ijk}\f$ computed from the first derivative of the
80 : /// spatial metric.
81 : ///
82 : /// Can be retrieved using `gr::Tags::SpatialChristoffelFirstKind`
83 : template <typename DataType, size_t SpatialDim, typename Frame>
84 1 : struct SpatialChristoffelFirstKindCompute
85 : : SpatialChristoffelFirstKind<DataType, SpatialDim, Frame>,
86 : db::ComputeTag {
87 0 : using argument_tags = tmpl::list<
88 : ::Tags::deriv<gr::Tags::SpatialMetric<DataType, SpatialDim, Frame>,
89 : tmpl::size_t<SpatialDim>, Frame>>;
90 :
91 0 : using return_type = tnsr::ijj<DataType, SpatialDim, Frame>;
92 :
93 0 : static constexpr auto function = static_cast<void (*)(
94 : gsl::not_null<
95 : tnsr::abb<DataType, SpatialDim, Frame, IndexType::Spatial>*>,
96 : const tnsr::ijj<DataType, SpatialDim, Frame>&)>(
97 : &christoffel_first_kind<SpatialDim, Frame, IndexType::Spatial, DataType>);
98 :
99 0 : using base = SpatialChristoffelFirstKind<DataType, SpatialDim, Frame>;
100 : };
101 :
102 : /// Compute item for spatial Christoffel symbols of the second kind
103 : /// \f$\Gamma^i_{jk}\f$ computed from the Christoffel symbols of the
104 : /// first kind and the inverse spatial metric.
105 : ///
106 : /// Can be retrieved using `gr::Tags::SpatialChristoffelSecondKind`
107 : template <typename DataType, size_t SpatialDim, typename Frame>
108 1 : struct SpatialChristoffelSecondKindCompute
109 : : SpatialChristoffelSecondKind<DataType, SpatialDim, Frame>,
110 : db::ComputeTag {
111 0 : using argument_tags =
112 : tmpl::list<SpatialChristoffelFirstKind<DataType, SpatialDim, Frame>,
113 : InverseSpatialMetric<DataType, SpatialDim, Frame>>;
114 :
115 0 : using return_type = tnsr::Ijj<DataType, SpatialDim, Frame>;
116 :
117 0 : static constexpr auto function = static_cast<void (*)(
118 : gsl::not_null<tnsr::Ijj<DataType, SpatialDim, Frame>*>,
119 : const tnsr::ijj<DataType, SpatialDim, Frame>&,
120 : const tnsr::II<DataType, SpatialDim, Frame>&)>(
121 : &raise_or_lower_first_index<DataType,
122 : SpatialIndex<SpatialDim, UpLo::Lo, Frame>,
123 : SpatialIndex<SpatialDim, UpLo::Lo, Frame>>);
124 :
125 0 : using base = SpatialChristoffelSecondKind<DataType, SpatialDim, Frame>;
126 : };
127 :
128 : /// Compute item for the trace of the spatial Christoffel symbols
129 : /// of the first kind
130 : /// \f$\Gamma_{i} = \Gamma_{ijk}\gamma^{jk}\f$ computed from the
131 : /// Christoffel symbols of the first kind and the inverse spatial metric.
132 : ///
133 : /// Can be retrieved using `gr::Tags::TraceSpatialChristoffelFirstKind`
134 : template <typename DataType, size_t SpatialDim, typename Frame>
135 1 : struct TraceSpatialChristoffelFirstKindCompute
136 : : TraceSpatialChristoffelFirstKind<DataType, SpatialDim, Frame>,
137 : db::ComputeTag {
138 0 : using argument_tags =
139 : tmpl::list<SpatialChristoffelFirstKind<DataType, SpatialDim, Frame>,
140 : InverseSpatialMetric<DataType, SpatialDim, Frame>>;
141 :
142 0 : using return_type = tnsr::i<DataType, SpatialDim, Frame>;
143 :
144 0 : static constexpr auto function = static_cast<void (*)(
145 : gsl::not_null<tnsr::i<DataType, SpatialDim, Frame>*>,
146 : const tnsr::ijj<DataType, SpatialDim, Frame>&,
147 : const tnsr::II<DataType, SpatialDim, Frame>&)>(
148 : &trace_last_indices<DataType, SpatialIndex<SpatialDim, UpLo::Lo, Frame>,
149 : SpatialIndex<SpatialDim, UpLo::Lo, Frame>>);
150 :
151 0 : using base = TraceSpatialChristoffelFirstKind<DataType, SpatialDim, Frame>;
152 : };
153 :
154 : /// Compute item for the trace of the spatial Christoffel symbols
155 : /// of the second kind
156 : /// \f$\Gamma^{i} = \Gamma^{i}_{jk}\gamma^{jk}\f$ computed from the
157 : /// Christoffel symbols of the second kind and the inverse spatial metric.
158 : ///
159 : /// Can be retrieved using `gr::Tags::TraceSpatialChristoffelSecondKind`
160 : template <typename DataType, size_t SpatialDim, typename Frame>
161 1 : struct TraceSpatialChristoffelSecondKindCompute
162 : : TraceSpatialChristoffelSecondKind<DataType, SpatialDim, Frame>,
163 : db::ComputeTag {
164 0 : using argument_tags =
165 : tmpl::list<SpatialChristoffelSecondKind<DataType, SpatialDim, Frame>,
166 : InverseSpatialMetric<DataType, SpatialDim, Frame>>;
167 :
168 0 : using return_type = tnsr::I<DataType, SpatialDim, Frame>;
169 :
170 0 : static constexpr auto function = static_cast<void (*)(
171 : gsl::not_null<tnsr::I<DataType, SpatialDim, Frame>*>,
172 : const tnsr::Ijj<DataType, SpatialDim, Frame>&,
173 : const tnsr::II<DataType, SpatialDim, Frame>&)>(
174 : &trace_last_indices<DataType, SpatialIndex<SpatialDim, UpLo::Up, Frame>,
175 : SpatialIndex<SpatialDim, UpLo::Lo, Frame>>);
176 :
177 0 : using base = TraceSpatialChristoffelSecondKind<DataType, SpatialDim, Frame>;
178 : };
179 :
180 : /// Compute item for spacetime Christoffel symbols of the first kind
181 : /// \f$\Gamma_{abc}\f$ computed from the first derivative of the
182 : /// spacetime metric.
183 : ///
184 : /// Can be retrieved using `gr::Tags::SpacetimeChristoffelFirstKind`
185 : template <typename DataType, size_t SpatialDim, typename Frame>
186 1 : struct SpacetimeChristoffelFirstKindCompute
187 : : SpacetimeChristoffelFirstKind<DataType, SpatialDim, Frame>,
188 : db::ComputeTag {
189 0 : using argument_tags =
190 : tmpl::list<DerivativesOfSpacetimeMetric<DataType, SpatialDim, Frame>>;
191 :
192 0 : using return_type =
193 : tnsr::abb<DataType, SpatialDim, Frame, IndexType::Spacetime>;
194 :
195 0 : static constexpr auto function = static_cast<void (*)(
196 : gsl::not_null<
197 : tnsr::abb<DataType, SpatialDim, Frame, IndexType::Spacetime>*>,
198 : const tnsr::abb<DataType, SpatialDim, Frame, IndexType::Spacetime>&)>(
199 : &christoffel_first_kind<SpatialDim, Frame, IndexType::Spacetime,
200 : DataType>);
201 :
202 0 : using base = SpacetimeChristoffelFirstKind<DataType, SpatialDim, Frame>;
203 : };
204 :
205 : /// Compute item for spacetime Christoffel symbols of the second kind
206 : /// \f$\Gamma^a_{bc}\f$ computed from the Christoffel symbols of the
207 : /// first kind and the inverse spacetime metric.
208 : ///
209 : /// Can be retrieved using `gr::Tags::SpacetimeChristoffelSecondKind`
210 : template <typename DataType, size_t SpatialDim, typename Frame>
211 1 : struct SpacetimeChristoffelSecondKindCompute
212 : : SpacetimeChristoffelSecondKind<DataType, SpatialDim, Frame>,
213 : db::ComputeTag {
214 0 : using argument_tags =
215 : tmpl::list<SpacetimeChristoffelFirstKind<DataType, SpatialDim, Frame>,
216 : InverseSpacetimeMetric<DataType, SpatialDim, Frame>>;
217 :
218 0 : using return_type = tnsr::Abb<DataType, SpatialDim, Frame>;
219 :
220 0 : static constexpr auto function = static_cast<void (*)(
221 : gsl::not_null<tnsr::Abb<DataType, SpatialDim, Frame>*>,
222 : const tnsr::abb<DataType, SpatialDim, Frame>&,
223 : const tnsr::AA<DataType, SpatialDim, Frame>&)>(
224 : &raise_or_lower_first_index<DataType,
225 : SpacetimeIndex<SpatialDim, UpLo::Lo, Frame>,
226 : SpacetimeIndex<SpatialDim, UpLo::Lo, Frame>>);
227 :
228 0 : using base = SpacetimeChristoffelSecondKind<DataType, SpatialDim, Frame>;
229 : };
230 :
231 : /// Compute item for the trace of the spacetime Christoffel symbols
232 : /// of the first kind
233 : /// \f$\Gamma_{a} = \Gamma_{abc}g^{bc}\f$ computed from the
234 : /// Christoffel symbols of the first kind and the inverse spacetime metric.
235 : ///
236 : /// Can be retrieved using `gr::Tags::TraceSpacetimeChristoffelFirstKind`
237 : template <typename DataType, size_t SpatialDim, typename Frame>
238 1 : struct TraceSpacetimeChristoffelFirstKindCompute
239 : : TraceSpacetimeChristoffelFirstKind<DataType, SpatialDim, Frame>,
240 : db::ComputeTag {
241 0 : using argument_tags =
242 : tmpl::list<SpacetimeChristoffelFirstKind<DataType, SpatialDim, Frame>,
243 : InverseSpacetimeMetric<DataType, SpatialDim, Frame>>;
244 :
245 0 : using return_type = tnsr::a<DataType, SpatialDim, Frame>;
246 :
247 0 : static constexpr auto function = static_cast<void (*)(
248 : gsl::not_null<tnsr::a<DataType, SpatialDim, Frame>*>,
249 : const tnsr::abb<DataType, SpatialDim, Frame>&,
250 : const tnsr::AA<DataType, SpatialDim, Frame>&)>(
251 : &trace_last_indices<DataType, SpacetimeIndex<SpatialDim, UpLo::Lo, Frame>,
252 : SpacetimeIndex<SpatialDim, UpLo::Lo, Frame>>);
253 :
254 0 : using base = TraceSpacetimeChristoffelFirstKind<DataType, SpatialDim, Frame>;
255 : };
256 : } // namespace Tags
257 : } // namespace gr
|