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 : #include <type_traits>
8 :
9 : #include "DataStructures/Tensor/IndexType.hpp"
10 : #include "DataStructures/Tensor/Metafunctions.hpp"
11 : #include "DataStructures/Tensor/Tensor.hpp"
12 : #include "DataStructures/VectorImpl.hpp"
13 : #include "Utilities/Array.hpp"
14 : #include "Utilities/Gsl.hpp"
15 : #include "Utilities/StdArrayHelpers.hpp"
16 : #include "Utilities/TMPL.hpp"
17 :
18 : /// \ingroup TensorGroup
19 : /// \brief Combines a time component of a tensor with spatial components to
20 : /// produce a spacetime tensor.
21 : ///
22 : /// \details Combines a time component of a tensor with spatial components to
23 : /// produce a spacetime tensor. Specifically, the components of the result
24 : /// are views to the inputs. Can do so for a tensor of any rank, but
25 : /// requires that the new index is the first index of the resulting tensor,
26 : /// replacing the position of the spatial index in the input spatial tensor.
27 : /// For instance, it may combine \f$ \phi \f$ with \f$ A^i \f$ into
28 : /// \f$ A^a = \left(\phi, A^i\right) \f$, or it may combine \f$ A^a{}_b{}_c \f$
29 : /// with \f$ B_i{}^a{}_b{}_c \f$ into
30 : /// \f$ C_a{}^b{}_c{}_d = \left(A^b{}_c{}_d, B_i{}^b{}_c{}_d\right)\f$,
31 : /// but it may not combine \f$ A^i{}_a \f$ with \f$ B^i{}_j{}_a \f$ to produce
32 : /// a tensor of the form \f$ C^i{}_a{}_b \f$.
33 : ///
34 : /// \tparam SpatialDim the number of spatial dimensions in the input and output
35 : /// tensors
36 : /// \tparam Ul whether the new index is covariant or contravariant (must match
37 : /// that of the spatial index of the input spatial tensor)
38 : /// \tparam Frame the frame of the new spacetime index (must match that of the
39 : /// spatial index of the input spatial tensor)
40 : template <size_t SpatialDim, UpLo Ul, typename Frame, typename DataType,
41 : typename SymmList, typename IndexList>
42 1 : void combine_spacetime_view(
43 : gsl::not_null<TensorMetafunctions::prepend_spacetime_index<
44 : Tensor<DataType, SymmList, IndexList>, SpatialDim, Ul, Frame>*>
45 : spacetime_tensor,
46 : const Tensor<DataType, SymmList, IndexList>& time_tensor,
47 : const TensorMetafunctions::prepend_spatial_index<
48 : Tensor<DataType, SymmList, IndexList>, SpatialDim, Ul, Frame>&
49 : spatial_tensor) {
50 : for (size_t storage_index = 0;
51 : storage_index < Tensor<DataVector, SymmList, IndexList>::size();
52 : ++storage_index) {
53 : const auto u_multi_index =
54 : Tensor<DataVector, SymmList,
55 : IndexList>::structure::get_canonical_tensor_index(storage_index);
56 : if constexpr (std::is_same_v<DataType, DataVector>) {
57 : const auto dtu_multi_index = prepend(u_multi_index, 0_st);
58 : make_const_view(
59 : make_not_null(&std::as_const(spacetime_tensor->get(dtu_multi_index))),
60 : time_tensor.get(u_multi_index), 0,
61 : time_tensor.get(u_multi_index).size());
62 : for (size_t i = 0; i < SpatialDim; i++) {
63 : const auto du_multi_index = prepend(u_multi_index, i + 1);
64 : const auto diu_multi_index = prepend(u_multi_index, i);
65 : make_const_view(make_not_null(&std::as_const(
66 : spacetime_tensor->get(du_multi_index))),
67 : spatial_tensor.get(diu_multi_index), 0,
68 : spatial_tensor.get(diu_multi_index).size());
69 : }
70 : } else {
71 : const auto dtu_multi_index = prepend(u_multi_index, 0_st);
72 : spacetime_tensor->get(dtu_multi_index) = time_tensor.get(u_multi_index);
73 : for (size_t i = 0; i < SpatialDim; ++i) {
74 : const auto du_multi_index = prepend(u_multi_index, i + 1);
75 : const auto diu_multi_index = prepend(u_multi_index, i);
76 : spacetime_tensor->get(du_multi_index) =
77 : spatial_tensor.get(diu_multi_index);
78 : }
79 : }
80 : }
81 : }
|