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/DataVector.hpp"
9 : #include "DataStructures/Tensor/Tensor.hpp"
10 : #include "DataStructures/Variables.hpp"
11 : #include "Utilities/ErrorHandling/Assert.hpp"
12 : #include "Utilities/Gsl.hpp"
13 : #include "Utilities/TMPL.hpp"
14 :
15 : /// \ingroup DataStructuresGroup
16 : /// Copy a given index of each component of a `Tensor<DataVector>` or
17 : /// `Variables<DataVector>` into a `Tensor<double>`, single point
18 : /// `Tensor<DataVector>`, or single-point `Variables<DataVector>`.
19 : /// Also works with `ComplexDataVector`.
20 : ///
21 : /// \note There is no by-value overload extracting to a
22 : /// `Tensor<DataVector>`. This is both for the practical reason that
23 : /// it would be ambiguous with the `Tensor<double>` overload and
24 : /// because allocating multiple `DataVector`s for the return type
25 : /// would usually be very inefficient.
26 : ///
27 : /// \see overwrite_point
28 : /// @{
29 : template <typename VectorType, typename... Structure>
30 1 : void extract_point(
31 : const gsl::not_null<Tensor<typename VectorType::value_type, Structure...>*>
32 : destination,
33 : const Tensor<VectorType, Structure...>& source, const size_t index) {
34 : for (size_t i = 0; i < destination->size(); ++i) {
35 : (*destination)[i] = source[i][index];
36 : }
37 : }
38 :
39 : template <typename VectorType, typename... Structure>
40 1 : Tensor<typename VectorType::value_type, Structure...> extract_point(
41 : const Tensor<VectorType, Structure...>& tensor, const size_t index) {
42 : Tensor<typename VectorType::value_type, Structure...> result;
43 : extract_point(make_not_null(&result), tensor, index);
44 : return result;
45 : }
46 :
47 : template <typename VectorType, typename... Structure>
48 1 : void extract_point(
49 : const gsl::not_null<Tensor<VectorType, Structure...>*> destination,
50 : const Tensor<VectorType, Structure...>& source, const size_t index) {
51 : ASSERT(destination->begin()->size() == 1,
52 : "Output tensor components have wrong size: "
53 : << destination->begin()->size());
54 : for (size_t i = 0; i < destination->size(); ++i) {
55 : (*destination)[i][0] = source[i][index];
56 : }
57 : }
58 :
59 : template <typename... Tags>
60 1 : void extract_point(
61 : const gsl::not_null<Variables<tmpl::list<Tags...>>*> result,
62 : const Variables<tmpl::list<Tags...>>& variables, const size_t index) {
63 : result->initialize(1);
64 : expand_pack((extract_point(
65 : make_not_null(&get<Tags>(*result)), get<Tags>(variables), index), 0)...);
66 : }
67 :
68 : template <typename... Tags>
69 1 : Variables<tmpl::list<Tags...>> extract_point(
70 : const Variables<tmpl::list<Tags...>>& variables, const size_t index) {
71 : Variables<tmpl::list<Tags...>> result(1);
72 : extract_point(make_not_null(&result), variables, index);
73 : return result;
74 : }
75 : /// @}
76 :
77 : /// \ingroup DataStructuresGroup
78 : /// Copy a `Tensor<double>`, single point `Tensor<DataVector>`, or
79 : /// single-point `Variables<DataVector>` into the given index of each
80 : /// component of a `Tensor<DataVector>` or `Variables<DataVector>`.
81 : ///
82 : /// \see extract_point
83 : /// @{
84 : template <typename VectorType, typename... Structure>
85 1 : void overwrite_point(
86 : const gsl::not_null<Tensor<VectorType, Structure...>*> destination,
87 : const Tensor<typename VectorType::value_type, Structure...>& source,
88 : const size_t index) {
89 : for (size_t i = 0; i < destination->size(); ++i) {
90 : (*destination)[i][index] = source[i];
91 : }
92 : }
93 :
94 : template <typename VectorType, typename... Structure>
95 1 : void overwrite_point(
96 : const gsl::not_null<Tensor<VectorType, Structure...>*> destination,
97 : const Tensor<VectorType, Structure...>& source, const size_t index) {
98 : ASSERT(source.begin()->size() == 1,
99 : "Cannot overwrite with " << source.begin()->size() << " points.");
100 : for (size_t i = 0; i < destination->size(); ++i) {
101 : (*destination)[i][index] = source[i][0];
102 : }
103 : }
104 :
105 : template <typename... Tags>
106 1 : void overwrite_point(
107 : const gsl::not_null<Variables<tmpl::list<Tags...>>*> destination,
108 : const Variables<tmpl::list<Tags...>>& source, const size_t index) {
109 : ASSERT(source.number_of_grid_points() == 1,
110 : "Must overwrite with a single point.");
111 : expand_pack((overwrite_point(make_not_null(&get<Tags>(*destination)),
112 : extract_point(get<Tags>(source), 0), index),
113 : 0)...);
114 : }
115 : /// @}
|